Changing a React Component's State with setState()

Unlike props, a component can change its state whenever it wants to and these will be saved until the component is destroyed. That being said, you should change your state carefully otherwise you will run into problems.

Why "carefully"? Well, first you need to know that any change of a component's state or props will automatically cause it to re-render so that the new values are reflected in your interface. This means frequent changes will make your code run slowly, which is never a pleasant user experience.

Second, React merges state so that old state and new state co-exist as a combined value. This means if your initial state has the name Bob and the country Australia, and you change the name to be Lucy, the country will remain set to Australia too.

The combination of those two is why React has a special way to set state called, cunningly, setState(). This takes new values to merge into the existing values, then triggers a re-render. So, let's modify the buttonClicked() method so that it changes the name while leaving the country intact:

Note that I've removed the call to this.forceUpdate() – it's no longer needed. In fact, calling forceUpdate() is only needed if React didn't spot a very deep state change, so we won't be using it from now on.

That new code does exactly what we said: it creates a newState object that has a new name key with a random name, and tells React to merge it into the component's current state by using this.setState(). Because state changes automatically trigger a re-render, you'll see a new name every time you click the button, but the country won't change.

In the unlikely event that you are making so many changes to state and/or props that the constant calls to render() are making your page run slowly, React has a solution: if you create a method called shouldComponentUpdate() and return false from it, your component won't be re-rendered.

To use this, either put some logic inside shouldComponentUpdate() to return either true or false depending on your needs, or alternatively you can always make it return false then use this.forceUpdate() to re-render as needed – that method will force a new render even if shouldComponentUpdate() returns false.

Buy the book for $10

Get the complete, unabridged Hacking with React e-book and take your learning to the next level - includes a 45-day no questions asked money back guarantee!

If this was helpful, please take a moment to tell others about Hacking with React by tweeting about it!