'How to retrieve the state across components in React.js?

I am trying to retrieve the value that the user types into a form and post it to the backend inside another component where some other data is already being posted to the backend through an onclick. All I want to do is add this value into that post request but I'm having trouble figuring out how to correctly retrieve the value of the state. I'm trying to console.log the value of 'username' and the console outputs:

class NameForm extends react__WEBPACK_IMPORTED_MODULE_0__.Component {
  constructor(props) {
    super(props);
    this.state = {
      username: ''
    };
    this.handleChange = this.handleChange.bind(th…

It seems to be outputting the actual snippet of code from my "NameForm.js" component which is where the form is created. Here is the whole code for that file:

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

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

    }
    
    handleSubmit (event) {  
        event.preventDefault();
        const username = this.state.username;
        alert('A name was submitted: ' + this.state.username);
        this.setState({username})
        // this.props.checkGuess = new NameForm(this.props.answer, this.state.username);
        // console.log(this.state.value)
    }
    checkGuess() {

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

Also here is the code for function that is sending the post request to the backend, this is located in another component "flashcard.js":

const checkGuess = (answer, stateValue) => {
        try {
            console.log(username)
            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: username
                })
            });
        } catch(e) {
            console.log(e)
        }
        if (answer === flashcard.answer) {
            setFlip(true)
            return
        }
        if (guess + 1 === MAX_TRIES) {
            setFlip(true)
        }

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

I think that 'username' is the incorrect variable to use but I don't know what is correct. I've also tried to console.log 'this.state.username' and that gives the error:

TypeError: Cannot read properties of undefined (reading 'state')
    at checkGuess (Flashcard.js:40:1)
    at onClick (Flashcard.js:102:1)

Also I've tried to use 'stateValue' and that returns 'undefined' in the console. Does anybody know what I'm doing wrong? I'm having a hard time understanding how to lift state in React even after trying to read their official documentation and other examples.

The structure of my app is as follows: App.js is the parent which has 2 children NameForm.js (where the form is) and FlashcardList.js (sets up all my flashcards into a grid to be displayed together). FlashcardList.js then has a child component Flashcard.js (sets up each flashcard). So I need to pass the state from NameForm.js to Flashcard.js because the post request is located inside Flashcard.js.



Solution 1:[1]

You should really consider creating an actions.js file to handle your API calls and using a global state management system such as Redux. However, in the meantime it looks like you're not consuming your props correctly. When you made the call to your function in another file you call:

this.props.checkGuess = new NameForm(this.props.answer, this.state.username);

Which is sending the answer and the username. Then in your checkGuess function you consume answer and stateValue then try to reference username directly. What you need to do here is simply rename your variable in the function signature of checkGuess to username from stateValue.

The signature then becomes:

const checkGuess = (answer, username) => {

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mcatoen