Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Shouldn't state be treated as immutable in React?

I notice the method of updating state presented in the Learn React Track often involves mutating the current state. For example, in this video, the current players state was changed by pushing a new player onto the players array. I thought state should be treated as immutable in React? So setting the state by creating copies of the old state combined with the new state. I'm not exactly sure of the reason why immutability is so important but I think it has something to do with React's state management and not bypassing it... I wonder if anyone could clarify?

1 Answer

Jacob Richter
Jacob Richter
11,210 Points

Hey Adam,

Great question. You should never mutate the state directly instead you should use the this.setState method available at all times.

You are right and you should never ever ever do this.state.pop() or otherwise as this skips the re-render of your component (that occurs during this.setState) and knocks things out of sync.

If you wish to make alterations to the state using push and pull as you have stated above I would first do a shallow copy of the state and then altering via mutation methods and returning the new arrays / objects via setState.

Such as:

let someArray = this.state.someArray
someArray.pop()
this.setState({someArray: someArray})

A more sophisticated method is to use the setState method in full which can take a function that is passed the current state, this is much better for keeping state in sync if you have many this.setState calls occuring at nearly the same time.

this.setState((state) => { someKey: state.someStateMutation }) 

For poping you should instead use

const newArray = oldArray.splice(-1,1) 

and for adding you can use the new spread syntax

const newArray = [...oldArray, newElement]

Please check out the new spread syntax introduced in ES7 which allows you to do shallow copies and pretty awesome functional techniques as well. There are plenty of resources on functional programming using Javascript and I urge you to check these out, you'll need them if you ever move to more advanced state management such as Redux or MobX and they allow you to do pretty cool things in relatively short amount of code.

Any other questions let me know. Jacob.