I encountered a weird bug in React the other day and this is the simplified version of it.
let count = 0;
export default function App() {
const [countState, setCountState] = useState(count);
const [countState2, setCountState2] = useState(count);
const increaseCount1 = () => ++count;
const handleClick = () => {
setCountState(() => increaseCount1());
};
const handleClick2 = () => {
setCountState2(() => countState2 + 1);
};
return (
<div className="App">
<h1>{countState}</h1>
<button onClick={handleClick}>Btn1</button>
<div>
<h1>{countState2}</h1>
<button onClick={handleClick2}>Btn2</button>
</div>
</div>
);
}
Here is the live demo https://codesandbox.io/s/side-effect-ryfwr
when Btn1
got clicked on, countState
will increase by 2 not by 1, while when Btn2
got clicked on, countState2
will increase by 1, which is expected. I was struggling to understand what caused countState
to increase by 2. Then I figured it out it has something to do with React's strict mode. It is mentioned in the article that Functions passed to useState, useMemo, or useReducer can be doubled invoked to detect side effects. Given that, I think what I have passed in setCountState
is a side effect i.e. setCountState(() => increaseCount1());
But I still don't quite understand why setCountState(() => increaseCount1());
is a side effect while setCountState2(() => countState2 + 1);
is fine. I need a mental model. Can someone help me understand this more deeply?