Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is react setState method immutable?

Following comes from React tutorial:

const squares = this.state.squares.slice();
squares[i] = 'X';
this.setState({squares: squares});

This code changes copied state.squares and assign it to orginal state.squares. Finally this changes original state.squares, so I think this is not different than mutable code like following:

this.state.squares[i] = 'X';

Is there some difference?

like image 353
Tetote Avatar asked Sep 15 '17 06:09

Tetote


People also ask

Is setState immutable?

Never mutate this. state directly, as calling setState() afterwards may replace the mutation you made. Treat this. state as if it were immutable.

Why React state should be immutable?

Why Immer works well for React State Immutability? In React, using an Immutable state enables quick and cheap comparison of the state tree before and after a change. As a result, each component decides whether to re-rendered or not before performing any costly DOM operations.

Why are React props immutable?

Properties in React are immutable, read-only objects used to pass down data from a parent to its child component. Props facilitate the transfer of a piece of state or functionality you wish to make accessible to a sub component down the hierarchy. Syntactically, props resemble the way attributes are written in HTML.

Why are we using setState whereas not mutating the state?

Instead, we should use setState() . One reason is, for a pure component, directly mutating state won't trigger the component re-render, which could cause some odd bugs. With setState() we can change the state without directly mutating it.

Should react state be treated as immutable?

React state should be treated as immutable. Never mutate this.state directly, as calling setState () afterwards may replace the mutation you made. Treat this.state as if it were immutable. Why? setState batches work behind the scenes. This means a manual state mutation may be overridden when setState is processed.

How to mutate the state of a React component?

This applies to React in many places. For example, you should never mutate the state property of a component directly, but only through the setState () method. In Redux, you never mutate the state directly, but only through reducers, which are functions.

When to use the setState method in ReactJS?

This method is really useful when we are setting a value in the state in such a way that it depends on its previous value. For example, toggling a boolean (true/false) or incrementing/decrementing a number. Click me! How to update an object with setState in ReactJS?

Why state changing is not working in ReactJS?

second reason, state changing is asynchronous in React, so you might have some other components changing state behind the scene while you are still referring to the old unchanged state, which result in wrong state values Show activity on this post. This code is immutable, because slice () method is used.


3 Answers

I do wonder about this question too. But I find that the answers were unsatisfactory. So here is my take

The answer is actually written in the doc itself http://reactjs.org/docs/state-and-lifecycle.html#do-not-modify-state-directly

so first reason, setState() triggers render()

second reason, state changing is asynchronous in React, so you might have some other components changing state behind the scene while you are still referring to the old unchanged state, which result in wrong state values

like image 119
grandia Avatar answered Sep 30 '22 19:09

grandia


This code is immutable, because slice() method is used. If you try:

someState = {squares: [1,2,3,4,5]}
squares = someState.squares.slice()

You'll get new array created by slice() method.

You can test it that way:

squares = someState.squares.slice()
squares2 = someState.squares
squares[0] = 9    // doesn't change someState
squares2[1] = 9   // changes someState
someState.squares // [1,9,3,4,5] - as I said

And if you have doubts about this.setState({squares: squares}); - yes, of course after running this you have new state, but in fact this state is not modified old state object, but new object created from old parts. So if you try:

oldState = this.state
this.setState({squares: squares})

You'll see that new state will differ than saved old:

this.state == oldState //false

In case of this.state.squares[i] = 'X'; oldState would be modified too and that is exactly what we call mutability. All copied parts of old state changes with it and that causes many problems.

like image 41
Karol Selak Avatar answered Sep 30 '22 19:09

Karol Selak


You can do this, but you should not, the reason behind is that, if you use

this.state.squares[i] = 'X';

It will be overridden with next

this.setState({squares: squares});

So, your app will not have accurate data.

From Doc:

Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

Check more about this in https://facebook.github.io/react/docs/react-component.html#state

like image 23
Jigar Shah Avatar answered Sep 30 '22 18:09

Jigar Shah