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

React实现汇率数据周期增减功能出现无限循环问题求解

问题原因
  • 定时器直接声明在组件顶层:组件每次因状态更新重渲染时,都会创建新的定时器实例,旧定时器没有被清理,累积的定时器不断触发状态更新,形成无限循环。
  • initialTime 是普通局部变量:每次组件重渲染都会被重置为 true,你在 setTimeout 中修改的是上一次渲染闭包内的变量值,对后续渲染不生效,涨跌切换逻辑完全失效。
  • setCurrencies 使用错误:初始状态声明为数组,但你在遍历中每次都传入单个货币的对象,不仅覆盖前一次更新的结果,还会导致状态类型和初始值不匹配。
  • 逻辑与需求不符:需求要求每5秒修改一次数值、1分钟切换涨跌方向,现有代码定时器间隔是1秒,也没有实现涨跌循环切换的逻辑。
修复方案
import { useState, useEffect, useRef } from 'react';

// 原始数据
const originData = [
  { AUD: "1.5876" }, { BGN: "1.9558" }, { GBP: "0.8527" }, { USD: "1.1820" },
  { UYU: "51.9732" }, { UZS: "12570.5509" }, { VEF: "252746931045.8590" },
  { VND: "27195.9489" }, { VUV: "130.1601" }, { WST: "3.0161" }, { XAG: "0.0449" },
  { XAU: "0.0006" }, { XCD: "3.1944" }, { XDR: "0.8306" },
];

function CurrencyComponent() {
  // 把初始数据转成对象格式方便操作,避免每次遍历数组
  const initCurrencies = Object.assign({}, ...originData.map(item => {
    const [key, val] = Object.entries(item)[0];
    return { [key]: Number(val) };
  }));
  const [currencies, setCurrencies] = useState(initCurrencies);
  // 用ref存涨跌方向,不会触发重渲染
  const isIncreasing = useRef(true);
  // 用ref存定时器id,方便清理
  const updateTimer = useRef(null);
  const directionTimer = useRef(null);

  useEffect(() => {
    // 每5秒更新一次数值
    updateTimer.current = setInterval(() => {
      setCurrencies(prev => {
        const newVal = {...prev};
        Object.keys(newVal).forEach(key => {
          // 保留4位小数避免精度问题,根据实际货币精度可以调整
          const delta = isIncreasing.current ? 0.0001 : -0.0001;
          newVal[key] = Number((newVal[key] + delta).toFixed(4));
        });
        return newVal;
      });
    }, 5000);

    // 每1分钟切换一次涨跌方向
    directionTimer.current = setInterval(() => {
      isIncreasing.current = !isIncreasing.current;
    }, 60000);

    // 组件卸载时清理所有定时器
    return () => {
      clearInterval(updateTimer.current);
      clearInterval(directionTimer.current);
    };
  }, []);

  // 测试打印,可以删除
  useEffect(() => {
    console.log('当前汇率:', currencies);
  }, [currencies]);

  // 业务渲染逻辑自行补充
  return <div>汇率展示</div>;
}

核心修复逻辑:

  • 所有定时器都放在 useEffect 回调里,仅组件挂载时执行一次,同时配置卸载清理逻辑,避免定时器泄漏。
  • 用 useRef 存储不参与渲染的状态(涨跌方向、定时器id),修改时不会触发组件重渲染,也不会在重渲染时被重置。
  • 初始状态统一转成对象格式,更新时先拷贝之前的状态再批量修改所有货币值,不会出现状态覆盖问题。
  • 完全匹配需求:每5秒修改0.0001,每60秒切换涨跌方向循环执行,新增toFixed处理避免浮点数精度溢出问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 05:00:00