CodePudding user response:
setState
calls are not what a human would consider "immediate". Instead, the calls to the state setter as queued inside React internal mechanisms. Consider this:
const [state, setState] = useState(0)
// somewhere
setState(state 1)
setState(state 1)
In this case, you do not end up with 2
but 1
, because while you call setState
twice to increment by one, you really are calling it as:
setState(1)
setState(1)
This is the exact issue in your code with the callbacks, you have
// enter
setState({ ...state, [i]: true })
// leave
setState({ ...state, [i]: false })
so when both get called, you apply the "leave" with the wrong previous state.
This is why setState
has another pattern, setState(prevState => nextState)
setState(prevState => prevState 1)
setState(prevState => prevState 1)
Like this, you do end up with the value 2
because the second call is then using the "correct" previous state.
In your case, you need:
// enter
setState(prevState => ({ ...prevState, [i]: true }))
// leave
setState(prevState => ({ ...prevState, [i]: false }))
CodePudding user response:
This is happening because you also keep the previous values in your state. You should update in this way
onMouseOver={() => {
setHover({
[i]: true
});
}}
onm ouseLeave={() => {
setHover({
[i]: false
});
}}
onm ouseOut={() => {
setHover({
[i]: false
});
}}