You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 12:45:48