错误代码示范:
let timer;
useEffect(() => {
getModelAlertInfoListTimely(filterRef.current);
timer = setInterval(() => {
getModelAlertInfoListTimely(filterRef.current);
}, 60 * 1000);
return () => {
clearInterval(timer);
};
}, [filterRef.current]);
//切换状态
const onRtSwitchChange = value => {
setRtSwitch(value);
if (value) {
timer = setInterval(() => {
getModelAlertInfoListTimely(filterRef.current);
}, 60 * 1000);
} else {
clearInterval(timer);
}
};
return(
<div className={css.operationSwitch}>
<Switch checked={rtSwitch} onChange={onRtSwitchChange} />
<span>实时刷新</span>
</div>
)
实际运行效果: 当value为false时,仍然会调用getModelAlertInfoListTimely()
从代码逻辑来看,getModelAlertInfoListTimely() 只会在 value 为 true 时被 setInterval 定时调用。当 value 为 false 时,clearInterval(timer) 会清除定时器,理论上不会继续调用 getModelAlertInfoListTimely()。
实际观察到 value 为 false 时仍然调用了 getModelAlertInfoListTimely(),可能的原因包括:
-
timer 变量未正确清除:
检查 timer 是否为全局变量或未正确重置。建议将 timer 声明为组件内的 useRef 或 useState 持久化变量,避免因重新渲染丢失引用。
-
clearInterval 未生效:
可能 timer 的值在 clearInterval 调用时已无效(例如被覆盖或未正确传递)。
-
异步延迟问题:
如果 value 快速切换(如短时间内从 true 变 false),可能存在尚未执行的定时任务。
修复建议:
// 使用 useRef 持久化 timer
const timerRef = useRef<NodeJS.Timeout | null>(null);
useEffect(() => {
getModelAlertInfoListTimely(filterRef.current);
timerRef.current = setInterval(() => {
getModelAlertInfoListTimely(filterRef.current);
}, 60 * 1000);
return () => {
clearInterval(timerRef.current);
};
}, [filterRef.current]);
const onRtSwitchChange = value => {
setRtSwitch(value);
if (value) {
// 先清除已有定时器
if (timerRef.current) clearInterval(timerRef.current);
timerRef.current = setInterval(() => {
getModelAlertInfoListTimely(filterRef.current);
}, 60 * 1000);
} else {
if (timerRef.current) {
clearInterval(timerRef.current);
timerRef.current = null; // 重置引用
}
}
};
return(
<div className={css.operationSwitch}>
<Switch checked={rtSwitch} onChange={onRtSwitchChange} />
<span>实时刷新</span>
</div>
)