reactjs - React useEffect 重启定时器
问题描述
我一直在尝试 useEffect 钩子,但遇到了一个我不知道要解决的问题。
我编写了一个简单的计数器示例,它在 useEffect 中使用 setTimeout 来更新值。
if (countState.stopWatch === 0) {
dispatch({ type: 'reset' });
}
else {
const timeId = setTimeout(() => {
console.log("Timeout " + JSON.stringify(countState));
if (countState.stopWatch > 0) {
dispatch({ type: 'decrement_stopwatch' });
}
}, 1000);
return () => {
clearTimeout(timeId);
};
}
});
该代码工作正常,但有一个问题。当函数被重新渲染时,它会导致计时器退出并重新设置,这会导致间隙(即计时器不是每 1 秒运行一次,而是每隔一秒加上重新渲染应用程序的时间)。
当我使用基于类的解决方案时,我在类构造函数中运行计时器,并且计时器运行平稳,因为它不会被重新渲染取消。
关于我如何在功能版本中解决这个问题的任何想法?
可以在此处找到包括基于函数和类的解决方案的完整代码:
https://github.com/jmc420/react_examples/blob/master/counter/hooks_counter/src/StopWatch.tsx
解决方案
我发现了解决方案是什么。如果 useEffect 在没有依赖关系的情况下使用,您会收到来自 react 的警告,但当计时器递减时计时器不会退出。然后你会得到引用过时的闭包变量的问题,但这可以通过使用 useRef 来解决。
推荐阅读
- c++ - 重新分配时的指针仍指向旧值
- java - SDK 不支持选定的 Java 版本 15(最多 14 个)
- php - 无法在保存后分配父类别
- java - 使用长类型字段排序在 Spark Java 数据集中不起作用
- python - Python 套接字接收函数
- c# - 如何在没有名称的按钮上触发点击事件
- r - R中的连续博伊斯指数(CBI)
- c# - 如何将 Azure AD SAML 连接到我现有的 .net webforms 应用程序?
- r - Levenshtein 距离:解决字符串变量拼写不一致的问题
- ionic-framework - 如何在关联的 Bitbucket 帐户中使用“离子登录”?