I'm building a REACT App using Hooks, and now I'm facing an issue when using useMemo()
and some event listener. i've, prepared a simpler demo of my problem on CodeSandBox: here's the link → https://codesandbox.io/s/mystifying-hertz-21jov?fontsize=14&hidenavigation=1&theme=dark .
Now, let me explain where's the problem: I have buttonData
which is computed using useMemo()
. Now, let's took a look into the console output:
At first, buttonData
is computed on first render, and buttonData.behavior
is equal to test1
. Then, when I enter the button, inside onMouseEnterButton
I use setTargetDOM
: this will trigger buttonData
to be recomputed, since setTargetDOM
is one of its dependencies.
So far, so good:
buttonData.behavior
is test1
;onMouseEnterButton
, and that right now buttonData.behavior
is test1
;targetDOM
has changed, we have computed again buttonData
, and now buttonData.beavhior
is equal to test2
; And now, here comes the problem, what I don't understand! I can somehow accept the fact that the fourth console line tells me that buttonDat.behavior
is still test1
, since we are still in the same function that changed targetDOM
and thus triggered buttonData
to change (even if I expected to see buttonData.behavior: test2
even in the fourth line.
What's even worste is that, inside onMouseMoveButton
I see buttonData.behavior
equals to test1
, and not test2
..
The question is simple.. Why? I mean, I thought implementing this way I had test2
, but I guess I'm missing some React Hook stuff right here.
onMouseMoveButton
and onMouseEnterButton
capture buttonData.behavior
on the first render and because you never update the event listeners they will always refer to the initial value of buttonData.behavior
What you can do is add buttonData.behavior
to the dependencies array of useLayoutEffect
and every time buttonData.behavior
changes it will run the returned function and remove the previous listeners and add new ones
React.useLayoutEffect(() => {
...
}, [buttonData.behavior])
Also, state updates are asynchronous so you in line 4 you can't really log
the updated state after you set it
setTargetDOM(e.currentTarget);
// this will never the updated value because
// the state updater hasn't run yet
console.log(buttonData.behavior);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.