It was a beautiful day, my day was going almost good but suddenly...
I encountered stale closures in React.useEffect()
This was my code, ahh... a simple and small code but good enough to frustrate you.
When you run this code, It will show
Hello Bucky
on screen.
Haha, Nah It'll not
The thing is it'll only show Hello + "", I mean only Hello.
Why?
because of closures.
Hey, what is closures?
Checkout this video
Okay got it? That video on closure was amazing isn't it...
Now let's continue.
Here are two ways you can solve this problem
The useEffect's dependency array
&
Using a ref instead of a useState
The useEffect's dependency array
On line 15 just put user in dependency array, so from now whenever user value will get updated the useEffect() will render again and new value of user will get set in line 14.
But, this approach will set greeting twice one with previous("") user value and one with updated("Bucky") user value as useEffect() will render twice.
Let's look into another better solution to tackle this stale closures issue.
Using a ref instead of a useState
What is useRef()?
As, in previous approach useEffect() was rendering twice, but in this useEffect() will only run once.
If you are thinking which is better, I believe it's depend more upon on your use case.
Cool... Now It's end, if you're having any suggestion in this article please update me in comment, I'll love to update this article with more better information. Thankyou Have a great day.
Top comments (4)
Don't use the closure value for initialization but initialize both states from the same fresh value instead.
Once asynchronous updates get involved things get even more interesting in terms of the number of renders:
Two renders:
Four renders:
Three renders:
Back to two renders:
Picking
useRef()
overuseState()
comes down to:value.current
is rebound to a new value - then useuseRef()
(Aside: another use ofuseRef()
that doesn't reference a DOM element: handleEvent & React )useEffect()
) requiring a re-render thenuseState()
has to be used.How React isn't reactive, and why you shouldn't care
Ryan Carniato for This is Learning ・ Mar 18 '21 ・ 6 min read
Deep dive: How do React hooks really work?
Major edit: Made implied fetch explicit by emulating it with a promise.
Thanks for explanation
The more correct solution would be this:
The setState just sets the state for the next render.
React is about simplicity. And you have no benefit in use useRef like this.
A better example for using useRef would be for the main purpose:
reactjs.org/docs/hooks-reference.h...
github.com/facebook/react/issues/1... You can read this also.