React函数组件setInterval无法获取更新props的更优方案咨询
问题解答:React函数组件setInterval中无法获取更新后的props值
问题根源
这是典型的闭包陷阱:Component1中的useEffect依赖数组为空,意味着它仅在组件挂载时执行一次。setInterval的回调函数捕获了挂载时的counter闭包,后续组件因counter更新重新渲染时,这个闭包不会同步更新,所以console.log始终输出初始值。
解决方案
方案1:将props加入useEffect依赖列表(更简洁)
直接把counter添加到useEffect的依赖数组中,每次counter更新时,自动清除旧的定时器并创建新的,新的回调会捕获最新的counter值:
const Component1 = ({ counter }) => { useEffect(() => { const intervalID = setInterval(() => { console.log(counter); }, 1000); return () => { clearInterval(intervalID); }; }, [counter]); // 加入counter作为依赖 return <h1>Component1 count: {counter}</h1>; };
这种方案无需额外创建ref,代码逻辑更直观,对于每秒更新的场景,定时器销毁重建的性能开销可以完全忽略。
方案2:使用useRef(无频繁定时器重建)
如果需要让定时器持续运行不中断,同时获取最新的props,你的原方案是可行的。不用担心ref的内存开销——单个ref占用的内存极小,完全不会影响性能。可以保持原写法,或者稍作优化(将ref赋值逻辑放到useEffect中,避免每次渲染都执行,但实际差异可忽略):
const Component1 = ({ counter }) => { const counterRef = useRef(counter); // 仅在counter更新时同步ref useEffect(() => { counterRef.current = counter; }, [counter]); useEffect(() => { const intervalID = setInterval(() => { console.log(counterRef.current); }, 1000); return () => { clearInterval(intervalID); }; }, []); return <h1>Component1 count: {counter}</h1>; };
方案选择
- 若定时器逻辑需要随props更新调整(比如不同counter值对应不同的定时行为),优先选方案1;
- 若需要定时器持续运行不中断,同时获取最新props,选方案2。
两种方案都是React中的正确实践,没有绝对的“最优”,需根据实际场景选择。
内容的提问来源于stack exchange,提问作者GAURAV
相关产品推荐
相关产品推荐

