React:为什么我们需要在计时器上使用useEffect ?



根据React文档以及stackoverflow计时器的每个例子,人们使用类似选项2 w/useEffect (+useState)的东西来创建一个可以启动/暂停/重置的计时器。

然而,我也能够通过单独使用useState在选项1中创建定时器。

为什么没有人依赖useState作为计时器?我理解useEffect在卸载/重新渲染期间清理,但这真的提高了性能吗?从useEffect中不断卸载和重新挂载,然后调用setValue,难道不会比仅仅执行一个调用setValue的常规函数慢吗?这两个选项都可以调用clearInterval,所以这两个选项都不足以进行清理吗?

还有,哪个计时器更"准确",选项1还是选项2?我相信我理解异步函数的事件循环是如何工作的,但在React中它对我来说变得有点模糊。是否存在多个异步函数积压的情况,并且以某种方式延迟了useEffect的触发,并使选项2中的计时器以比选项1更慢的速度滴答(即不是每秒滴答,并且缓慢地落后于其他计时器)?

谢谢!

选项1 -常规函数+ useState

const [time, setTime] = useState(1500);
const [startPauseBtnText, setStartPauseBtnText] = useState('START');
const timeID = useRef(null);
const startPauseTime = () => {
if (timeID.current) {
clearInterval(timeID.current);
timeID.current = null;
setStartPauseBtnText('START');
} else {
timeID.current = setInterval(() => {
setTime((prevTime) => {
return prevTime - 1;
});
}, 1000);
setStartPauseBtnText('PAUSE');
}
};
const resetTime = () => {
clearInterval(timeID.current);
timeID.current = null;
setTime(1500);
}; 

选项2 - useEffect + useState

const [isActive, setIsActive] = useState(false);
const [time2, setTime2] = useState(1500);
useEffect(() => {
let timeID2;
if (isActive) {
timeID2 = setInterval(() => {
setTime2((prevTime) => {
return prevTime - 1;
});
}, 1000);
}
return () => clearInterval(timeID2);
}, [isActive, time2]);
const resetTime2 = () => {
setIsActive(false);
setTime2(1500);
};

useEffect允许您在组件卸载时清除计时器(通过返回的清理函数),而不是让它运行并触发未来不再存在的组件的状态更新尝试。

最新更新