Skip to content Skip to sidebar Skip to footer

React Setstate Not Re-rendering

In below code, state of Test is updating but its not re-rendering. I have updated the state of parent on button click on change of which I expected it to rerender the whole compone

Solution 1:

For a number to re render in the child component you need to make following changes to your code:

In current scenario value of id in changeId function is event, so you can't do ++id. You have to update it to:

changeId() {
    this.setState({
        id: ++this.state.id
    })
}

and for child component to re render the props value, you have to listen if there is any change in props. For that use componentDidUpdate lifecycle of react. Like this:

componentDidUpdate(prevProps){
   if (this.props.id !== prevProps.id) {
    this.setState({id: this.props.id});
  }
}

The other way is don't store props.id in child state. Use it directly in render.

classButtonextendsReact.Component {

  render() {
      return(
          <div>
              'hi ' +  {this.props.id}
              <br/><buttontype='submit'onClick={this.props.handleSubmit}>
                  submit
              </button></div>
      )
    }
}

classAppextendsReact.Component {
  constructor(props) {
      super(props)
      this.state = {
          id: 1
      }
      this.changeId = this.changeId.bind(this)
  }
  changeId() {
      this.setState({
          id: ++this.state.id
      })
  }
  render() {
      return(
          <Buttonid={this.state.id}handleSubmit={this.changeId}/>
      )
    }
}

ReactDOM.render(<App />, document.getElementById('root'))
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script><divid="root" />

Solution 2:

You haven't actually passed handleSubmit as a prop to the Button component. Assuming you want changeId() to be called when you click the button, try this:

classTestextendsReact.Component {
    constructor(props) {
        super(props)
        this.state = {
            id: 1
        }
        this.changeId = this.changeId.bind(this)
    }
    changeId() {
        console.log('change id called', id)
        this.setState({
            id: ++id
        })
    }
    render() {
        return(
            <Buttonid={id}handleSubmit={this.changeId}/>
        )
    }
}

Solution 3:

We can further optimise the component by doing something like this -: Highlights -:

  • changeId() { changed to changeId = () => { (fat arrow notation), if we use this we don't need this.changeId = this.changeId.bind(this);
  • Don't really need another component specially for button, can combine it in same component.
importReact, {Component} from'react'; 
exportdefaultclassTestextendsReact.Component {
        constructor(props) {
            super(props)
            this.state = {
                id: 1
            }
        }
        changeId = () => {
            this.setState({
                id: ++this.state.id
            })
        }
        render() {
            return(
               <div>
                    'hi ' +  {this.state.id}
                    <br/><buttontype='submit'onClick={this.changeId}>
                        submit
                    </button></div>
            )
        } }

Solution 4:

The example for componentWillReceiveProps worked in my case, when I wanted to update child component of React on setState of parent component:

componentWillReceiveProps(props) {
        this.setState({
          currentID: props.currentID
        });
      }

Post a Comment for "React Setstate Not Re-rendering"