DEV Community

loading...

Discussion on: React hooks: get the current state, back to the future

Collapse
dan_abramov profile image
Dan Abramov

So this might seem unexpected in this case. But let's consider an equivalent case that looks a bit more concrete than a counter.

handleFollowClick() {
  setTimeout(() => {
    alert('Followed: ' + this.props.user.name);
  }, 5000)
}
Enter fullscreen mode Exit fullscreen mode

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:

handleFollowClick() {
  const {user} = this.props;
  setTimeout(() => {
    alert('Followed: ' + user.name);
  }, 5000)
}
Enter fullscreen mode Exit fullscreen mode

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.

function handleFollowClick() {
  // There is no "this", the "user" is always
  // the one corresponding to this event handler.
  setTimeout(() => {
    alert('Followed: ' + user.name);
  }, 5000)
}
Enter fullscreen mode Exit fullscreen mode

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.

Collapse
scastiel profile image
Sébastien Castiel Author

Thanks Dan, it kind of confirms (and explains very well) what I suspected 🙂

Collapse
dan_abramov profile image
Dan Abramov

I wrote up a more detailed explanation. overreacted.io/how-are-function-co...