So… when I do something like:
const [count, setCount] = React.useState(0);
// in something else now
setCount(5);
Now, I don’t really know when setCount
is going to update… I can’t be sure. Obviously, the current solution is
React.useEffect(() => {
// ... then do something
}, [count]);
but why not make setCount
async?
// count might not be 5, but will definitely have updated.
setCount(5).then(count => {
// ... then do something
})
This is a question about React’s hook’s API design. I am not asking about how I can achieve something, more why the library is built this way.
3
Answers
That is a good look in, to the design. Well there are some reason why
setState
is notasynchronous
. Based on my experience and perspective, it is mainly the performance optimization factor why thesetState
isnot asynchronous
in React.To understand this further lets say, when you call
setState
in React, the component is scheduled for are-render
but is not executed right away. Instead, it does there-render
at the conclusion of the cycle after batching all state modifications that take place within a single render cycle.Now if the
setState
wereasynchronous
, Each state change would start a new re-render cycle, which would be less effective. SetState may be made synchronous so that React can group together many state modifications and only need to re-render the component once.Ultimately, React’s design choice to make
setState
synchronous
is a compromise between efficiency and complexity, and it has been successful in helping React components manage state.setState is actually not async in reality because an async function is expected to return a promise. But It does appear as async, because of something called batching of states i.e. The way in which react actually updates the state. If you want to understand it even deeply… learn about batching of states in react.
React is fundamentally designed around writing declarative code, instead of imperative code.
It’s not about time, it’s about dependencies.
You are not supposed to ask "when
setCount
is going to update", you should not even think about code like "do this, and then do something else", you should only think about "the state should be this value now", and "state B depends on state A".I.e. your example
says "as soon as this value is set, do something else…".
That is imperative code, and thus violates the basic concepts of React (i.e. writing declarative code).
declare:
Instead you should declare what you want the state to be now.
E.g. you should say "The variable
count
should be5
":dependencies:
And then you specify dependencies, e.g. you might say somewhere else in your code "
count
items of my data should be displayed", so theitems
array depends oncount
, e.g.:side effects:
If e.g. not enough data is available, you might use a side effect, aka.
useEffect
, that depends oncount
and the available data, and might fetch some additional data, e.g.:Links