如何让Hook中延迟执行的函数获取React状态最新值?
解决React定时器函数无法获取最新状态值的问题
方法1:使用函数式更新setState
React的setState支持传入函数形式的参数,该函数会接收当前最新的状态值作为参数,返回新的状态。这种方式能确保无论函数何时执行,都能拿到实时的状态值,完美适配定时器场景。
修改后的代码:
import { useEffect, useState } from "react"; export default function Stopwatch(){ const [stopwatch, setStopwatch] = useState(0); function updateStopwatch(){ console.log("Updating stopwatch to latest value"); // 函数式更新,prevStopwatch为当前最新状态 setStopwatch(prevStopwatch => prevStopwatch + 1); } useEffect(() => { const interval = setInterval(updateStopwatch, 1000); return () => clearInterval(interval); }, []); // 无需依赖stopwatch或updateStopwatch return ( <div> <h1>{stopwatch}</h1> </div> ); }
方法2:用useRef存储最新状态
useRef创建的引用对象在组件生命周期内始终保持引用不变,可以用来同步存储状态的最新值,定时器函数直接读取ref的current属性即可获取实时状态。
修改后的代码:
import { useEffect, useState, useRef } from "react"; export default function Stopwatch(){ const [stopwatch, setStopwatch] = useState(0); const stopwatchRef = useRef(0); // 状态更新时同步ref的值 useEffect(() => { stopwatchRef.current = stopwatch; }, [stopwatch]); function updateStopwatch(){ console.log("Updating stopwatch from ", stopwatchRef.current, " to ", stopwatchRef.current + 1); setStopwatch(stopwatchRef.current + 1); } useEffect(() => { const interval = setInterval(updateStopwatch, 1000); return () => clearInterval(interval); }, []); return ( <div> <h1>{stopwatch}</h1> </div> ); }
方法3:结合useCallback与依赖数组(不推荐此场景)
如果需要将函数加入useEffect的依赖列表,可以用useCallback缓存函数,并将状态加入依赖数组。但这种方式会导致每次状态变化时,定时器都会被清除并重新创建,对于秒表这类持续运行的场景来说冗余且没必要,仅作为思路参考:
import { useEffect, useState, useCallback } from "react"; export default function Stopwatch(){ const [stopwatch, setStopwatch] = useState(0); // 用useCallback缓存函数,依赖stopwatch const updateStopwatch = useCallback(() => { console.log("Updating stopwatch from ", stopwatch, " to ", stopwatch + 1); setStopwatch(stopwatch + 1); }, [stopwatch]); useEffect(() => { const interval = setInterval(updateStopwatch, 1000); return () => clearInterval(interval); }, [updateStopwatch]); // 依赖updateStopwatch return ( <div> <h1>{stopwatch}</h1> </div> ); }
总结
对于秒表这类需要基于最新状态进行更新的场景,**方法1(函数式更新)**是最优选择,代码简洁高效,无需额外的引用或依赖处理,完全利用React内置的setState特性解决问题。
内容的提问来源于stack exchange,提问作者Menas
相关产品推荐
相关产品推荐

