简体   繁体   中英

setState doesn't work when function passed through props is used

I have a React component ( App.js ) that does ajax requests (via axios). The values of parameters passed through these requests are taken from inputs fields manipulated by the user. Based on the response it updates its state.

sendValue(value) {
  const url = `${myURl}/c${value}\r`;
  axios.get(url)
        .then(res=>{
              this.setState({
                       data:res.data
              })
         })
         .catch(err => {
            console.log('err', err);
         })  
}

And then in the return statement this function is passed as a prop to a child component:

<Child sendValue={this.sendValue}>

The child component ( Child.js ) has a couple of input fields. This child component has its own state. When the input fields are changed, the values will be passed to the axios function through the props.

handleChange(e) {
      const { value } = e.target;
      this.setState({ input: value }, console.log('state', this.state));
      this.props.sendValue(`${value}\r`);
}

The actual input element looks like this:

<input
    value={this.state.value}
    onChange={this.handleChange}
 />

If I leave out this line this.props.sendValue(${value}\\r); the state gets updated and the value of the input fields change (the console.log as a callback function proves this, and also that the actual value of the input field changes). But when I leave it in, nothing changes, the state never gets updated, console.log never gets called.

Why?

How do I fix this?

I assume your Child component would be like below, the problem is in the Child's constructor, I guess you initialize the state there.

class Child extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      value: 'init-value' // or null
    }

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
   ....
  }

  render() {
    return (
      ....
      <input value={this.state.value} onChange={this.handleChange} />
      ....
    );
  }
}

this.props.sendValue is a function passed from (belongs to) Parent Component and it includes setState statement. If it was triggered, Parent Component re-rendering would happen.

In the handleChange(e) function, after

this.setState({ input: value }, console.log('state', this.state));

which changes the Child's state

this.props.sendValue(`${value}\\r`);

re-render the Parent Component, and of course, Child is involved in. So the state value is initialized again, and it seems like nothing happens.

Maybe you would like to using props from Parent Component to give value to state.value .

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