Not modifying State in React directly

We all have heard about warning that

do not change the react state directly!

What is this warning about? Why should we not change it directly? Let's find out. Before moving on to the explanation, let's see what react state is and ways of changing it.

State

A short definition would be "The state object is where you store property values that belongs to the component. When the state object changes, the component re-renders."

Generally in JavaScript, when we have to change or alter an object completely or a property of it, we just refer to it directly and change it's value. But this is not the case with state object in react. It is never recommended to change the state directly and do it like

this.state.property=y or this.state=x

This can lead to various bugs and issues that are difficult to track down and optimize the code. Also other properties who are dependent on that state might also start behaving weirdly giving errors.

This is why it is recommended to use this.setState method to have any state updates.Here are two main reasons to use it :

  • setState method work in batches, which means that you cannot expect the setState to do the state update immediately. Calls to setState are asynchronous.React batches different setState together to save resources and improve performance. Therefore if you make the changes to state directly, it might be possible that a setState command may change the value of the state overriding it's value.
  • If we use React pure component or shouldComponentUpdate() method, they will do a shallow compare using === operator. Now if we directly modify the state, due to it being object reference we will get the value to be same. This will lead to that component not being rendered as the state received as props is same as the already present value.

Let's see this with an example. Here we have a simple random number generator which gets a random number and display it to screen in a form of list. The main component being App component which holds the state.

code1.PNG

This App component hold the buttons for updating the list directly(wrong way) and indirectly(right way).

The list is being rendered by a pure component RenderCounter.

render component.PNG

What happens if we click the button for indirect method.

code1.PNG

The list gets a new random no and it gets updated.

Now let us click the button for direct state change.

code 2.PNG

Nothing changed! Now let us again use the correct way to check what happened.

code 3.PNG

There you go. The list gets abruptly updated with all the random no. generated earlier. So what happened ?

When we directly modified the state, the main state object was modified. Now the RenderCounter method depends on the state object to render the list. It has a componentDidUpdate() which check the props(next and current) and finds them to be same. So it skips the render and we do not get the output on the screen.

Here we saw why we shouldn't mutate state directly, even if we call setState immediately. Instead always use setState with new objects and arrays. Hope this article helped with you understand the concept better.

Happy Coding!