Yesterday I was browsing new React's website react.dev that includes up-to-date documentation and tutorials out of boredom. While browsing, I have come across this section called Queueing a Series of State Updates and it sparked an interest in me. After reading, I have learned something new from it.
Now I always knew that React doesn't instantly update state when you tell it you to do so. I always knew this in the back of my head but never really knew what is happening inside the hood.
Here's an example:
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
};
// For somebody who just started to learn React you might
// think that count would be 3 right? Nope
It turns out that React will waits for the codes inside the event handlers to finish before processing your state updates and then re-render. React calls it batching. For an analogy, it's like a waiter is waiting for you to make all your orders then run to the kitchen to give it to the cook.
In React's context, it means React will wait until you call a bunch of setState then group it together and make a single re-render to improve performance. This process is called batching.
So in order to immediately update the state multiple times before next render, you can React's Updater Function.
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
setCount((count) => count + 1); // called updater function
// next render count = 2
};
Here's a psuedocode to demonstrate how React's queue work inside the hood.
let count = 0 //Initial value
const queue = [
setCount(count + 1), // return count = 1
setCount(count => count + 1) // return count as 1+1 = 2
]
rerender()
So if you want to simultaneously update the state without waiting for the next render you can use Updater Function to make it happen.
In conclusion, today we have learnt that React has an operation called batching that take multiple setState call and wait to execute it at once for improvement. And we also learn how to update state immediately using Updater Function without waiting for next render as well. I hope you learn something new today!
Thank you!
Top comments (5)
Hey! I don't know, but it's not working.
Hey if you're wondering why, because the counter you have put in console.log() is actually the old state. After calling a bunch of set function, the screen hasn't re-render yet so that's why you're seeing old state on console.log which is 0. To see changes, you need to put useEffect and put a dependency of counter. After that you should see 2.
Pls also remember that
won't give you 3. You have to call an updater function which is
setCounter((counter) =>counter + 1);
to increment the value one by oneHey, thank you for your feedback. I know that we need to use useEffect(), but you didn't write in article about it. So, I decided that it works without useEffect(), but with updater function.
I only somewhat recently figured out the same thing after browsing the update react docs page out of curiosity and looking for info on making custom Hooks by extracting stateful code outside of our main files.
This ability to take out queuing almost completely removed all of my useEffect queries that was handling tiered levels of state change across 3-4 state variables.
Granted... in hindsight I could've just handled all of my state in a single state object instead of having so many state variables!
Thanks for taking the time to write up and share!
Thank you for your comment!