简体   繁体   中英

passing data from child to parent component - react - via callback function

passing data from child to parent component via callback function but somehow it's not working. what am I doing wrong here? passing data from child to parent component - react - via callback function

https://codepen.io/silentarrowz/pen/GEMQEP?editors=0010

and here's the code

class App extends React.Component{
    constructor(props){
      super(props);
      this.state={
        input:'this is the input for now'
      }
   //this.handleInput=this.handleInput.bind(this);   
    }

    handleInput(x){
      this.setState({
        input:x
      });
      alert(this.state.input);
    }

  render(){
    return(
      <div>
        <h1>Passing props from Child to Parent Component</h1>
        <Child getInput={this.handleInput} />
        here's the input: {this.state.input}
        </div>
    );
  }
 }

class Child extends React.Component{
  constructor(){
    super();
    this.state={
      text:''
        }
    }
  passingProps(e){
    var newInput=e.target.value;
    //alert(newInput);
   this.setState({
     text:newInput
    });
  this.props.getInput(this.state.text);
  }

  render(){
    return(
      <div>
      <input type="text" placeholder="please input a name..." onChange={this.passingProps} />

        </div>

    )
  }
}

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

There are a couple of issues.

1) You have to bind passingProps

constructor(){
    super();
    this.state={
      text:''
    }
    this.passingProps = this.passingProps.bind(this);
}

2) this.setState is asynchronous, so it's not guaranteed that this.state.text will be set to the value you want by the time you pass it to this.props.getInput . You can either do

this.props.getInput(newInput)

or

this.setState({ text: newInput }, () => {
  this.props.getInput(this.state.text);
})

to resolve that issue.

class App extends React.Component{
constructor(props){
  super(props);
  this.state={
    input:'this is the input for now'
  }
  this.handleInput=this.handleInput.bind(this);   
}

handleInput(event){
  let value = event.target.value;
  this.setState({
    input:value
  });
}

render(){
   return(
     <div>
       <h1>{this.state.input}</h1>
       <Child getInput={this.handleInput} />
     </div>
   );
  }
}

 class Child extends React.Component{
   constructor(){
      super(props);
}

render(){
   return(
     <div>
     <input type="text" placeholder="please input a name..." onChange={this.props.getInput} />
    </div>

     )
   }
}

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

Here is the answer for your question. I hope your proplem is solved.

this is not automatically bound in your passingProps function. Try arrow function syntax to bind it.

passingProps = e => {
  var newInput=e.target.value;
  //alert(newInput);
  this.setState({
    text:newInput
  });
  this.props.getInput(this.state.text);
}

In your Child Component, you have written following code:

passingProps(e){
  var newInput=e.target.value;
  //alert(newInput);
  this.setState({
     text:newInput
  });
  this.props.getInput(this.state.text);
}

The issue is due to the asynchronous behaviour of setState function. It means you can not call setState on one line and expect its updates on next line. Use the callback function of setState to call the function of parent component just like this:

passingProps(e){
  var newInput=e.target.value;
  //alert(newInput);
  this.setState({ text: newInput }, () => {
     this.props.getInput(this.state.text);
  })
}

Same thing is happening in handleInput function of App component.

Two things that you need to correct it:

  1. if you want to access new state, you don't use this.state.input after this.setState({input: 'xxx'}) . Here is reason why not it.
  2. this.passingProps = this.passingProps.bind(this) is defined what this is current scope. when you use this in component's function, this need to be bind.

Changed codepen

You can create a method in parent that accepts some data and then sets the received data as parent state. Then pass this method to child as props. Now let the method accept child state as input and then let the method set the received child state as parent state.

将孩子的状态传递给父母

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM