首页 > 解决方案 > 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

标签: reactjsreact-hooksuse-effect

解决方案


我发现了解决方案是什么。如果 useEffect 在没有依赖关系的情况下使用,您会收到来自 react 的警告,但当计时器递减时计时器不会退出。然后你会得到引用过时的闭包变量的问题,但这可以通过使用 useRef 来解决。


推荐阅读