React函数组件状态未变更却重渲染的异常问题咨询
Hey Peter, let's walk through exactly what's happening with your React component and custom hook—this is a great question that gets to the heart of how React's state updates and effects work!
Why your initial setNum(0) doesn’t trigger a re-render
React has a built-in performance optimization: it skips re-renders when the new state value is identical to the old one. When your interval first fires, num is already 0, so calling setNum(0) doesn’t change anything—React correctly decides not to re-render the component, which matches your expectation.
What happens after clicking the Increment button
Once you click Increment, setNum(num + 1) updates num from 0 to 1. This state change triggers a re-render, and here’s where the behavior you’re confused about comes in:
Your custom hook’s
useEffectwon’t run again
TheuseEffectinuseAutoIncrementhas an empty dependency array[]. In React, this means the effect only runs once—right when the hook mounts. Even though the hook re-runs every time the parent component re-renders, the dependency array never changes (it’s always an empty array), so React won’t re-execute this effect. The original interval you created on mount keeps running, which is why it still callssetNum(0)every 5 seconds.Your main component’s
useEffectshould run (double-check your logs!)
The main component’suseEffectlistsnumas a dependency. When the interval fires again after you click Increment,setNum(0)changesnumfrom 1 back to 0—this is a clear state change, so React should trigger this effect to run. If you didn’t see the log for this, it might be a timing issue in your testing, but if you run through the flow step-by-step, you should see it appear.
A quick note on closures
One thing to keep in mind: even though your component re-renders multiple times, the setNum function React gives you is stable—it doesn’t change between re-renders. That’s why your interval can keep calling it successfully, even though it was created in the initial mount’s closure. If you ever start using other variables from the hook’s scope in the interval, you’d need to handle closure issues (like adding those variables to the effect’s dependency array), but that’s not a problem here.
内容的提问来源于stack exchange,提问作者Peter89

