I have this simple example of a component that uses useRef() to count the number of times my component has rendered, and useState() to maintain some state:
const {useState, useRef} = React;
const App = () => {
const [counter, setCounter] = useState(0);
const renderCount = useRef(0);
const onClick = () => {
setCounter(1);
}
renderCount.current++;
alert("rendering"); // executes 3 times, not twice.
return <div>
<p>Render count: {renderCount.current}</p>
<button onClick={onClick}>{counter}</button>
</div>
}
ReactDOM.render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>
When I run the snippet above, the alert triggers and the ref counter is incremented due to the first render. When I click the button for the first time, setCounter(1) is called, which cuases the component to rerender/reexecute (as expected) causing the alert to appear for a second time and the ref counter to increase. When I click the button for the second time, setCounter(1) runs (which isn't updating the state since it is already 1). As the state isn't changing, I would expect that there is no rerender needed and so my App component wouldn't be executed again. However, I instead see a third alert, indicating that the component was executed again, but the ref counter doesn't increase, nor does the rendered output change after the second click. Further clicks of the button show no alerts as expected. My question is why does React execute my App component again when the state doesn't change (ie: on the second click of the button)?
