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
相关产品推荐
相关产品推荐

