Hacker News new | ask | show | jobs
by Stoids 2689 days ago
Perhaps I'm just a bit dumb here, but a few of these comments confused me.

> However, this is a common source of mistakes if you’re not very familiar with JavaScript closures.

> The problem is that useEffect captures the count from the first render. It is equal to 0. We never re-apply the effect so the closure in setInterval always references the count from the first render, and count + 1 is always 1. Oops!

Perhaps I'm not understanding the second comment fully... This behavior is completely counter to how Javascript closures work in my mental model. I'm trying to figure out how a state hook differs in execution from a normal variable in module scope.

How does it differ from this [1] example.

[1] https://jsfiddle.net/xuz09cow/1/

2 comments

The difference is that closedVariable would be created inside intervalFn (the component). In addition, the intervalFn may run many times, but the interval will only be set up once. This example illustrates the problem: https://jsfiddle.net/ov2msa4e/

Your code avoids the closure problem, but closedVariable would be more like a static variable — it'd be shared by every instance of the hook. Probably not what you intended!

Thank you for the example, Jake! It was very helpful. You and Jason's answer cleared it up for me.
The difference is subtle (and took me a bit to figure out!). In the article's example component, the component's "main" function gets re-run on every render and a new `count` variable is created each time. The effect function is only run once at the very first render, and only captures the value from this first render.

I'm having a little trouble explaining the difference well, I think this jsfiddle illustrates the incorrect case the article is talking about representatively: https://jsfiddle.net/7fLnvz5c/

Thanks Jason, this was very helpful for me. I think I was having trouble making the mental jump from reading the code as a normal function with state vs how a component instance is called and handled by React at runtime--your example helped me make that hurdle.