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

React中每秒拉取数据,仅在数据变更时更新State避免冗余重渲染

解决方案

直接在定时任务里完成数据拉取、对比和状态更新,不需要额外的ref或双State,就能避免冗余重渲染:

const MyComp = () => {
    const [data, setData] = useState([]);

    useEffect(() => {
        // 定义拉取并更新数据的函数
        const fetchAndUpdate = async () => {
            try {
                const returnedArray = await apiFetch();
                // 对比新数据和当前state,不一致才更新
                if (!arraysEqual(returnedArray, data)) {
                    setData(returnedArray);
                }
            } catch (err) {
                console.error('拉取数据失败:', err);
            }
        };

        // 立即执行一次
        fetchAndUpdate();
        // 设置每秒执行的定时器
        const timer = setInterval(fetchAndUpdate, 1000);

        // 组件卸载时清除定时器
        return () => clearInterval(timer);
    }, [data]); // 依赖data,确保每次data更新后,回调里能拿到最新的data

    // 自定义数组对比函数(比JSON.stringify高效,且能处理更复杂的场景)
    const arraysEqual = (arr1, arr2) => {
        if (arr1.length !== arr2.length) return false;
        for (let i = 0; i < arr1.length; i++) {
            // 如果是对象,需要递归对比;如果是基本类型直接比较
            if (typeof arr1[i] === 'object' && typeof arr2[i] === 'object') {
                if (!objectsEqual(arr1[i], arr2[i])) return false;
            } else if (arr1[i] !== arr2[i]) {
                return false;
            }
        }
        return true;
    };

    // 辅助的对象对比函数
    const objectsEqual = (obj1, obj2) => {
        const keys1 = Object.keys(obj1);
        const keys2 = Object.keys(obj2);
        if (keys1.length !== keys2.length) return false;
        for (const key of keys1) {
            if (typeof obj1[key] === 'object' && typeof obj2[key] === 'object') {
                if (!objectsEqual(obj1[key], obj2[key])) return false;
            } else if (obj1[key] !== obj2[key]) {
                return false;
            }
        }
        return true;
    };

    return (
        <div>
            {JSON.stringify(data)}
        </div>
    );
};

关键说明:

  • 把拉取-对比-更新放在同一个流程里,没有额外的中间状态或ref,减少不必要的组件更新触发点。
  • 用自定义对比函数替代JSON.stringify,后者性能差,还会因为对象键顺序、undefined值等出现误判。
  • useEffect依赖数组加入data,确保回调能捕获到最新的state值,解决之前定时器拿不到最新state的问题。
  • 组件卸载时清除定时器,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Aleksa Ristic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 13:15:40