Component State
What does setState
do?
setState()
schedules an update to a componentโs state
object. When state changes, the component responds by re-rendering.
What is the difference between state
and props
?
props
(short for โpropertiesโ) and state
are both plain JavaScript objects. While both hold information that influences the output of render, they are different in one important way: props
get passed to the component (similar to function parameters) whereas state
is managed within the component (similar to variables declared within a function).
Here are some good resources for further reading on when to use props
vs state
:
Why is setState
giving me the wrong value?
In React, both this.props
and this.state
represent the rendered values, i.e. whatโs currently on the screen.
Calls to setState
are asynchronous - donโt rely on this.state
to reflect the new value immediately after calling setState
. Pass an updater function instead of an object if you need to compute values based on the current state (see below for details).
Example of code that will not behave as expected:
incrementCount() {
// Note: this will *not* work as intended.
this.setState({count: this.state.count + 1});
}
handleSomething() {
// Let's say `this.state.count` starts at 0.
this.incrementCount();
this.incrementCount();
this.incrementCount();
// When React re-renders the component, `this.state.count` will be 1, but you expected 3.
// This is because `incrementCount()` function above reads from `this.state.count`,
// but React doesn't update `this.state.count` until the component is re-rendered.
// So `incrementCount()` ends up reading `this.state.count` as 0 every time, and sets it to 1.
// The fix is described below!
}
See below for how to fix this problem.
How do I update state with values that depend on the current state?
Pass a function instead of an object to setState
to ensure the call always uses the most updated version of state (see below).
What is the difference between passing an object or a function in setState
?
Passing an update function allows you to access the current state value inside the updater. Since setState
calls are batched, this lets you chain updates and ensure they build on top of each other instead of conflicting:
incrementCount() {
this.setState((state) => {
// Important: read `state` instead of `this.state` when updating.
return {count: state.count + 1}
});
}
handleSomething() {
// Let's say `this.state.count` starts at 0.
this.incrementCount();
this.incrementCount();
this.incrementCount();
// If you read `this.state.count` now, it would still be 0.
// But when React re-renders the component, it will be 3.
}
When is setState
asynchronous?
Currently, setState
is asynchronous inside event handlers.
This ensures, for example, that if both Parent
and Child
call setState
during a click event, Child
isnโt re-rendered twice. Instead, React โflushesโ the state updates at the end of the browser event. This results in significant performance improvements in larger apps.
This is an implementation detail so avoid relying on it directly. In the future versions, React will batch updates by default in more cases.
Why doesnโt React update this.state
synchronously?
As explained in the previous section, React intentionally โwaitsโ until all components call setState()
in their event handlers before starting to re-render. This boosts performance by avoiding unnecessary re-renders.
However, you might still be wondering why React doesnโt just update this.state
immediately without re-rendering.
There are two main reasons:
- This would break the consistency between
props
andstate
, causing issues that are very hard to debug. - This would make some of the new features weโre working on impossible to implement.
This GitHub comment dives deep into the specific examples.
Should I use a state management library like Redux or MobX?
Itโs a good idea to get to know React first, before adding in additional libraries. You can build quite complex applications using only React.