setState with a Function

Vivian Lin
Jul 27, 2017 · 2 min read

With the React library, apps are built with encapsulated components that manage their own state, and if you’ve built a React app before components are something you’re very familiar with.

And what is state again? The state contains data specific to a component that may change over time, state is a plain Javascript object, and state is meant to be immutable. Therefore, we change the state by setting it with the setState function, where we will pass it the attribute and value pair that we want to change as so

this.setState({ someProperty: someValue })

So we pass setState() the object what we want it to update to and it merge with the current state. But we can also pass setState()a function. The function takes two arguments the previous state, and the current props. So let’s say we were making a counter app, and when we wanted to increment the counter we would do

this.setState({ counter: this.state.counter + 1 })

What we can also do is this

this.setState({ counter: (state, props) => { count: return state + 1 } })

Yes the above two statements do the same thing. State updates may be asynchronous, which means that React may batch multiple setState() calls into a single update. Meaning that if we had multiple setState() functions, React may merge them together.

increaseCountBy3 = () => {
this.setState({ counter: this.state.counter + 1 })
this.setState({ counter: this.state.counter + 1 })
this.setState({ counter: this.state.counter + 1 })
}

You would expect this to increment the counter by 1 by three times. Actually though, React merges them, and the last function comes out on top, as it ‘overwrites’ the others. So counter would actually only increase by 1. By passing setState a function, the functions will be ‘queued’ and setState will execute each one.

function increment (state, props) {
return { counter: state.count + 1 }
}
increaseCountBy3Functional = () => {
this.setState(increment)
this.setState(increment)
this.setState(increment)
}

With this all the functions will be ‘queued’ and will go through each one, thus incrementing counter to 3. And also with a function, it can be separated from the component class. The function can be declared outside of the component class, making it reusable.

As our applications get bigger and more complex, states and props may constantly changing, which makes this.state less reliable and the value may potentially not be what you would expect. Passing setState a function is the way to go if you’re setting state based off the current state or current props.

Demo of this by Sophia Shoemaker

Sources:

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade