TransWikia.com

React - I am passing state from a child to a parent component but the state value is off by one update cycle

Stack Overflow Asked by Tresk33 on December 18, 2021

I am currently using the the following code to pass a state value to a parent component. However, the input text if off by one character. I know that it is due to the fact that I am changing state and passing it in the same function but how would I fix this? I can’t seem to get my head around it.

Here is my code:

import React from 'react';
import {render} from 'react-dom';

class App extends React.Component {
  constructor() {
    super();
    this.parentmethod = this.parentmethod.bind(this);
    this.state = {
      datafromChild: ''
    };
  }
  //here 'data' represents the data recieved from the child when this method gets called inside the child
  parentmethod(data) {
    this.setState({
      datafromChild: data
    });
  }
  
  render() {
    return (
      <div>
        <Child methodfromparent={this.parentmethod} /> 
        <br/><br/>
        <hr/><strong>Inside Parent</strong>
        <h5>Data from Child:<br />{this.state.datafromChild}
        <hr/>
        </h5>
      </div>
    );
  }
}


class Child extends React.Component {
  constructor() {
    super();
    this.handleChange = this.handleChange.bind(this);
    this.state = {
      data: ''
    };
  }
  
 
  
  handleChange(event) {
    this.setState({
      data: event.target.value
    });
    this.props.methodfromparent(this.state.data);

  }

  render() {
    return (
      <div>
     <hr/><strong>Inside Child</strong>
          <input type="text" onChange={this.handleChange} />
         <hr/>
       
      </div>
    );
  }
}

render(
  <App />,
  document.getElementById('root')
);

2 Answers

SetState is indeed asynchronous and both your requests will not fire at the same time. To make sure that this.props.methodfromparent(this.state.data) is using the updated value of this.state.data, you can use the setState callback to make sure your first request is complete before actioning the second one as below:

handleChange(event) {
    this.setState({
      data: event.target.value
    },
    () => this.props.methodfromparent(this.state.data) // the callback here
    );
}

Answered by Anthony on December 18, 2021

In your child component change

handleChange(event) {
    this.setState({
      data: event.target.value
    });
    this.props.methodfromparent(this.state.data);
}

to this

handleChange(event) {
    this.setState({
      data: event.target.value
    });
    this.props.methodfromparent(event.target.value);
}

setState is asynchronous. So when you run the parent method it is not receiving the most up to date value, it's receiving the value from the previous render. Rather than sending the parent the state, just send it the same value that you're setting in your child.

Answered by Chris on December 18, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP