In the code below, I expected:
state: 0
state: 1
But, result is:
state: 0
state: 1
state: 1
I thought setState
works only once(0 -> 1
). But 1 -> 1
works again.
export default function App() {
const [state, setState] = useState(0);
console.log('state: ', state);
useEffect(() => {
setState(1);
}, [state])
return <></>
I tried another case. Set state to 1 on scroll event.
In this case, result is what I expected.
state: 0
state: 1
export default function App() {
const [state, setState] = useState(0);
console.log('state: ', state);
const onScroll = () => {
setState(1)
}
return (
...
onScroll={onScroll}
)
What’s the difference between the examples? (react version: 18.2.0)
2
Answers
state
is0
WhenApp
is rendered.Then Effect is called and
state
is changed(0 -> 1) that causes re-rendering.Effect is called again after re-rendering, changes the state of
state
and re-rendering happens again. (1 -> 1)The dependency array is identical at this time, no more Effect calls, no more state changes, no more re-renderings.
State changes in Effect causes re-rendering. The point is that there is no state change after re-rendering in your second example.
To get the expected result, the dependency array should be empty, so that the logic inside the useffect will be executed only once.
useEffect(() => { setState(1); }, [])
Also, it is redundant to keep the same state (which is updated inside useEffect logic) in dependency array