DEV Community

💤sleepy sanjay💤
💤sleepy sanjay💤

Posted on

need help lifting state to another component in react

I have been really struggling to lift the state of this form data to be sent with some other data that i'm already successfully posting to the backend. I'm trying to have the user enter their username in the top of the page and then send that username to the backend with the other data. When trying to console log the state when inside the component i want to lift it too, i was getting 'undefined' in the console for the longest time but now I'm getting a part of the form component that i created being displayed in the console when trying to console log the state. this is what is being displayed in the console when trying to log the state:

```"onLoad Flashcard.js:35 class NameForm extends react_WEBPACK_IMPORTED_MODULE_0_.Component { constructor(props) { super(props); this.handleChange = event => { this.setState({ value: event.target.value …

here is the code for my NameForm.js file which is where i create the form:



import React from "react"
import CheckGuess from './Flashcard'


export default class NameForm extends React.Component {
    constructor(props) {
      super(props);
      this.state = {value: ''};   
      this.handleChange = this.handleChange.bind(this);
      this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange = (event) => {
        this.setState({value: event.target.value});
    }

    handleSubmit = (event) => {  
        alert('A name was submitted: ' + this.state.value);
        this.props.CheckGuess(this.props.answer, this.state.value);
        event.preventDefault();
    }
    CheckGuess() {

    }

    render() {
      return (
          <div>
            <form onSubmit={this.handleSubmit}>
                <label>
                    Name:
                    <input type="text" value={this.state.value} onChange={this.handleChange} />
                </label>
                <input type="submit" value="Submit" />

            </form>
          </div>
      );
    }
}

and here is the code for my flashcard.js file which contains the CheckGuess function which sends  the  other data to the backend and is where i would like to send the username as well:



Enter fullscreen mode Exit fullscreen mode

import React, { useState, useEffect, useRef } from 'react'
import NameForm from './NameForm'
import value from './NameForm'

export default function Flashcard({ flashcard }) { // recieving flashcard prop from our mapping in flashcardlist.js, each w a unique id

const MAX_TRIES = 4
// const [incorrect, setIncorrect] = useState(incorrect)
const [guess, setGuess] = useState(0)
const [flip, setFlip] = useState(false)
const [height, setHeight] = useState('initial') //sets the state for our initial height to be replaced by the max height

const frontEl = useRef() // lets us have a reference from the front and back through every rerendering of them
const backEl = useRef()

// const callDouble = () =>{
 //   checkGuess();
  //  postData();
Enter fullscreen mode Exit fullscreen mode

// }

async function postData() {


}



const CheckGuess = (answer, stateValue) => {
    try {
        console.log(value)
        let result = fetch('http://127.0.0.1:5000/post', {
            method: 'POST',
            mode: 'no-cors',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',

            },
            body: JSON.stringify({
                key: `${Date.now()}`,
                question: flashcard.question,
                answer: flashcard.answer,
                options: flashcard.options,
                guess: answer,
                user: stateValue
            })
        });
    } catch(e) {
        console.log(e)
    }
    if (answer === flashcard.answer) {
        setFlip(true)
        return
    }
    if (guess + 1 === MAX_TRIES) {
        setFlip(true)
    }

    setGuess(guess + 1)
    // setIncorrect(true)
}

function setMaxHeight() {
    const frontHeight = frontEl.current.getBoundingClientRect().height //gives us dimensions of the rectangle but we only need the height
    const backHeight = backEl.current.getBoundingClientRect().height
    setHeight(Math.max(frontHeight, backHeight, 100)) // sets the height (setHeight) to the maximum height of front or back but the minimum is 100px
}

useEffect(setMaxHeight, [flashcard.question, flashcard.answer, flashcard.options]) //anytime any of these change then the setMaxHeight will change
useEffect(() => {
    window.addEventListener('resize', setMaxHeight) //everytime we resize our browser, it sets the max height again
    return () => window.removeEventListener('resize', setMaxHeight) //removes the eventlistener when component destroys itself
  }, [])
Enter fullscreen mode Exit fullscreen mode

return (

    onClick={() =&gt; postData()}<br>
    className={<code>card ${flip ? 'flip' : ''}</code>} // if flip is true classname will be card and flip, if flip isnt true it will just be card<br>
    style={{ height: height }} //setting height to the variable height
Enter fullscreen mode Exit fullscreen mode
    // onClick={() => setFlip(!flip)} // click changes it from flip to non flip
>
    <div className="front" ref={frontEl}>
        {flashcard.question}
        <div className='flashcard-options'>
            {flashcard.options.map(option => {
                return <div key={option} onClick={() => CheckGuess(option)} className='flashcard-option'>{option}</div>
            })}
        </div>
    </div> 
    <div onClick={() => setFlip(!flip)} className='back' ref={backEl}>
        {flashcard.answer}        
    </div>

</div>

)
}
// setting the front to show the question and the answers by looping through the options to make them each an option with a class name to style
// back shows the answer

and then i render the NameForm inside my app.js function so that the form sits nicely above all the flashcard components:



import React, { useState, useEffect } from "react"
import FlashcardList from "./FlashcardList"
import './app.css'
import axios from 'axios' // makes importing from api easy
import NameForm from './NameForm'
import checkGuess from './Flashcard'
import flashcard from "./Flashcard"
import value from './NameForm'



export default function App() {
    const [flashcards, setFlashcards] = useState([])

    useEffect(() => {
        axios.get('http://127.0.0.1:5000/')
        .then(res => {
            setFlashcards(res.data.results.map((questionItem, index) => { // mapping over api to get objects "questionItem" and the index of each one
                const answer = decodeString(questionItem.correct_answer) // setting the correct_answer objects from api to answer
                const question = decodeString(questionItem.question)
                const options = [
                    ...questionItem.incorrect_answers.map(a => decodeString(a)), answer // spreading incorrect_answers objects into an array with answer at the back to set all of them into options
                ]
                return {
                    id: question, // sets the id to the index from the api and the exact time to make sure its always unique
                    question: question, // setting question objects from api to question
                    answer: answer, // already defined above
                    options: options.sort(() => Math.random() - .5), // sorting all the options randomly
                    user: value
                }
            }))
        })
    }, [])

    function decodeString(str) {
        const textArea = document.createElement('textarea')
        textArea.innerHTML= str
        return textArea.value // function brings all of our objects into this new element and decodes all of the encoded html
    }



    return (

           <div>
               <NameForm answer={flashcard.answer} checkGuess={checkGuess} />

                <div className="container">
                    <FlashcardList flashcards={flashcards} />
                </div>
            </div>
    )
}

 how can i get the actual state value inside that component? any help is greatly appreciated ive been trying to figure this out for a while and i have trouble with lifting state.










Top comments (0)