为什么第二个参数是[], 这个定时器还是会每秒执行一次呢?

在function component中,引入如下代码,第二个参数是[],按理说setInterval第一次执行后,触发rerender,在之前就会被…
关注者
2
被浏览
530

3 个回答

第一:因为你依赖为空数组[],意味着不会有任何引起effect变化的因素,即触发rerender并不会再次进入effect,且只有等到组件销毁的时候才会clearInterval,即执行销毁函数
第二:因为依赖为空,然后你effect里面用了setInterval,意味着每秒会调用setReRender
第三:setReRender参数是回调函数,每次会+1,所以也就有了你所说的 发现每隔1s就render一次

综上:要只执行一次,直接将setInterval改为setTimeout,clearInterval改为clearTimeout不就好?

useEffect 中,第二个参数 [] 的作用是告诉React只有在组件挂载和卸载的时候才会运行该 useEffect 回调函数。所以在组件挂载时, setInterval 会被执行,然后每隔1秒 setReRender 会被调用,触发组件重新渲染。由于 setInterval useEffect 回调函数的返回值中被清除了,所以在组件卸载时,计时器也会被清除。但是,由于 setInterval 的执行是异步的,当组件重新渲染时, setInterval 可能还未被清除,所以会继续执行,导致组件重新渲染。如果你想在组件重新渲染时清除计时器,可以在组件的 useEffect 回调函数中添加一个清除计时器的操作。

如果你想在组件重新渲染时清除计时器,可以添加一个监听组件重新渲染的 useEffect 回调函数,然后在该回调函数中清除计时器。修改后的代码如下所示:

useEffect(() => {
  const interval = setInterval(() => {
    setReRender(count => count + 1);
  }, 1000);
  return () => clearInterval(interval);
}, []);
useEffect(() => {
  return () => clearInterval(interval);
}, [reRender]);

在这个例子中,第一个 useEffect 回调函数仍然是在组件挂载和卸载时才会运行,用于创建计时器并清除计时器。而第二个 useEffect 回调函数会在组件重新渲染时运行,用于清除计时器。它的第二个参数是一个数组,包含了 reRender 变量,表示当 reRender 变量的值发生改变时,该 useEffect 回调函数会运行。所以当组件重新渲染时,第二个 useEffect 回调函数会运行,并清除计时器。当组件重新渲染时,第二个 useEffect 回调函数会运行,并清除之前创建的计时器,防止计时器继续执行。这样就可以保证计时器只在组件挂载时创建,并在组件卸载或重新渲染时被清除。完整代码如下所示:

import React, { useState, useEffect } from 'react';
function Timer() {
  const [reRender, setReRender] = useState(0);
  useEffect(() => {
    const interval = setInterval(() => {
      setReRender(count => count + 1);
    }, 1000);
    return () => clearInterval(interval);
  }, []);
  useEffect(() => {
    return () => clearInterval(interval);
  }, [reRender]);
  return (