export function App(props) {
const [number,setNumber] = useState(0);
console.log(number,'one')
useEffect(()=>{
console.log(number,'two')
setNumber(1);
},[number]);
console.log(number,'three')
return (
<div className='App'>
{number}
</div>
);
}
const { useState, useEffect } = React;
function App(props) {
const [number,setNumber] = useState(0);
console.log(number,'one')
useEffect(()=>{
console.log(number,'two')
setNumber(1);
},[number]);
console.log(number,'three')
return (
<div className='App'>
{number}
</div>
);
}
ReactDOM.createRoot(document.querySelector("#root")).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>
Given the code as above, I expected the output of console.log to be as follows
Expected output
0 one
0 three
0 two
1 one
1 three
1 two
Because during the initial rendering, the value of 'number' changed to 1. In the subsequent renderings, even if setNumber(1) is called, I expected 'number' not to change, so I thought there would be no re-rendering.
However, the actual output was as follows
Actual output
0 one
0 three
0 two
1 one
1 three
1 two
1 one
1 three
I was under the impression that if the state values are the same, no re-render would occur. However, even though the state values did not change, why is there an additional re-render happening?
This sequence can be explained by the following order of events.
App
component renders with the initial value0
fornumber
. This causes the output0 one
and0 tree
.useEffect
callback is fired. This causes the output0 two
.useEffect
calledsetNumber
(from0
to1
) React will register a state updated and re-render the component. Causing the output1 one
and1 tree
.useEffect
number
dependency changed from0
to1
theuseEffect
callback is invoked again. Causing the output0 two
.useEffect
calledsetNumber
(from1
to1
) React will register a state update (even though you use the same value) and re-render the component. Causing the output1 one
and1 tree
.useEffect
callback is not called this time because the dependencynumber
did not change. So this is where the render stops.If you want to avoid the last render, you should not call
setNumber
if the value is already what it should be.