Do you see the bug in this code? If the user prop changes before the timeout finishes (e.g. because you navigated to a different profile), you would "follow" the wrong person!
How would you fix it? With a class, one way to fix it is to destructure early:
Many people wouldn't notice the difference, but this code takes care to remember which user you referred to at the time of the click.
So how does this relate to Hooks? With Hooks, the code behaves like the second snippet by default. You always get the values in the event handlers that were actually rendered.
functionhandleFollowClick(){// There is no "this", the "user" is always// the one corresponding to this event handler.setTimeout(()=>{alert('Followed: '+user.name);},5000)}
As you described, a ref is a way to "escape" that snapshot time in time and peek into the future. In many cases you don't want it; but it's there for when you need it. It takes time to adjust to a new default though.
So this might seem unexpected in this case. But let's consider an equivalent case that looks a bit more concrete than a counter.
Do you see the bug in this code? If the
user
prop changes before the timeout finishes (e.g. because you navigated to a different profile), you would "follow" the wrong person!How would you fix it? With a class, one way to fix it is to destructure early:
Many people wouldn't notice the difference, but this code takes care to remember which
user
you referred to at the time of the click.So how does this relate to Hooks? With Hooks, the code behaves like the second snippet by default. You always get the values in the event handlers that were actually rendered.
As you described, a ref is a way to "escape" that snapshot time in time and peek into the future. In many cases you don't want it; but it's there for when you need it. It takes time to adjust to a new default though.
Thanks Dan, it kind of confirms (and explains very well) what I suspected π
I wrote up a more detailed explanation. overreacted.io/how-are-function-co...