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

React中如何让setInterval随状态变更触发重渲染并更新请求参数

现有代码的问题

  • useEffect的依赖数组为空,闭包会一直捕获初始的depth=20,后续修改depth后定时器里拿到的还是旧值
  • 没有实现首次加载立即执行getData,需要等5秒才会触发第一次请求
  • depth更新后不会销毁旧定时器、创建对应新depth的新定时器

修复后完整代码

import React, { useState, useEffect } from "react";

// 组件名首字母要大写,符合React组件规范
const Chart = () => {
  const [depth, setDepth] = useState(20);
  const [chartData, setChartData] = useState({});

  // 封装数据请求逻辑,避免重复代码
  const fetchData = () => {
    const data = getData(depth);
    setChartData(data);
  };

  useEffect(() => {
    // 首次加载/ depth更新时立即执行一次请求,不用等5秒
    fetchData();
    // 创建新定时器,使用最新的depth值
    const interval = setInterval(fetchData, 5000);
    // 组件卸载/ depth更新时销毁旧定时器
    return () => clearInterval(interval);
  }, [depth]); // 把depth加入依赖,depth变化就重新执行effect逻辑

  return (
    <div>
      <div>
        <DropdownButton id="dropdown-basic-button" title="Depth Percentage">
          <Dropdown.Item onClick={() => setDepth(5)}>5%</Dropdown.Item>
          <Dropdown.Item onClick={() => setDepth(20)}>20%</Dropdown.Item>
        </DropdownButton>
      </div>
      <div>
        {/* 渲染图表逻辑 */}
      </div>
    </div>
  );
};

export default Chart;

额外注意事项

如果你的getData是异步接口请求,建议加效验标记避免竞态问题:

useEffect(() => {
  let isActive = true;
  const fetchData = async () => {
    const data = await getData(depth);
    // 只有当前effect是激活状态才更新数据,避免旧请求覆盖新数据
    if (isActive) setChartData(data);
  };
  fetchData();
  const interval = setInterval(fetchData, 5000);
  return () => {
    isActive = false;
    clearInterval(interval);
  };
}, [depth]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 00:06:09