React组件每隔5秒刷新至满足停止条件的状态读取问题
问题原因分析
你的代码核心问题是闭包捕获旧值:useEffect的依赖数组为空,意味着它只会在组件首次渲染时执行一次,里面的status变量被闭包捕获,永远是初始值''。后续setStatus更新状态后,定时器里的status不会同步更新,导致停止逻辑永远无法触发。
解决方案
方案1:使用useRef保存最新状态(推荐)
useRef的current属性是可变的,不会被闭包捕获,能始终拿到最新的status值:
import { useState, useEffect, useRef } from 'react'; import axios from 'axios'; const YourComponent = () => { const [status, setStatus] = useState(''); // 0:failed, 1:waiting, 2:success const statusRef = useRef(status); // 同步最新status到ref useEffect(() => { statusRef.current = status; }, [status]); useEffect(() => { const interval = setInterval(() => { // 读取ref中的最新状态 if (statusRef.current !== '2' && statusRef.current !== '0') { handleClickRefresh(); } else { // 满足停止条件时清除定时器 clearInterval(interval); } }, 5000); // 组件卸载或重新渲染时清除定时器 return () => clearInterval(interval); }, []); const handleClickRefresh = async () => { try { const res = await axios.get('...', { headers: { // 你的请求头配置 } }); if (res.status === 202) { setStatus('1'); // waiting } else if (res.status === 200) { setStatus('2'); // success } } catch (error) { setStatus('0'); // fail } }; return ( <div>当前状态:{status}</div> ); }; export default YourComponent;
说明
- 用
statusRef同步最新的status值,确保定时器能拿到实时状态 - 当状态变为
2(成功)或0(失败)时,立即清除定时器停止刷新 - 仅在组件首次渲染时创建一次定时器,避免频繁销毁重建的性能损耗
方案2:给useEffect添加status依赖
通过监听status变化,动态创建/销毁定时器:
import { useState, useEffect } from 'react'; import axios from 'axios'; const YourComponent = () => { const [status, setStatus] = useState(''); // 0:failed, 1:waiting, 2:success useEffect(() => { // 已达到停止条件,无需创建定时器 if (status === '2' || status === '0') return; const interval = setInterval(() => { handleClickRefresh(); }, 5000); return () => clearInterval(interval); }, [status]); // 依赖status,状态变化时重新执行 const handleClickRefresh = async () => { try { const res = await axios.get('...', { headers: { // 你的请求头配置 } }); if (res.status === 202) { setStatus('1'); // waiting } else if (res.status === 200) { setStatus('2'); // success } } catch (error) { setStatus('0'); // fail } }; return ( <div>当前状态:{status}</div> ); }; export default YourComponent;
说明
- 每次
status变化时,旧定时器会被清除,再根据新状态决定是否创建新定时器 - 逻辑更直观,但状态变化频繁时会多次创建/销毁定时器,性能略逊于方案1
内容的提问来源于stack exchange,提问作者Andrea Mattone
相关产品推荐
相关产品推荐

