了解 useEffect 第二个参数

时间:2020-12-23 14:34:25

标签: reactjs react-native react-hooks use-effect

我做了一些对我的案例有好处的事情,但我不明白它是如何工作的,我很乐意解释评论。

  • 我尝试执行每 5 秒更改一次背景图像的功能。

1.我的第一次尝试是: (例如,我有包含 3 个图像的 mainImages 数组。)

    const [index, setIndex] = useState(0);
    useEffect(() => {
    const interval = setInterval(() => {
              setIndex(index+1)
             (index > mainImages.length-1)? console.log("Bigger",index):console.log("smaller","i="i)
    }, 5000);
    return () => clearInterval(interval);
    }, []);
  • 在这种情况下。 每 5 秒我得到 -"更小",i=0 - 即使在 3 个或更多间隔之后的每个间隔 奇怪的部分:图像的变化如预期。甚至索引仍然为0。

2.我的第二次尝试:我在索引和图像中也得到了我所期望的。

  • 它之间的唯一变化是我把 [index] 用于使用 effect sec 参数。

         useEffect(() => {
          thesame....
     }, [index]);
    
  • 在这种情况下。 每 5 秒我就会得到正确的控制台 (

    每 5 秒我得到 -“更小”,i=0

       "smaller",i=1 
       "smaller",i=2
       "Bigger",i=3.......
    

所以我的问题是:在幕后发生了什么,它的影响如何?它是如何工作的?

1 个答案:

答案 0 :(得分:1)

依赖数组用于决定何时扔掉旧效果并开始新效果。因此,对于空数组,该效果仅在安装时运行一次,然后在卸载时进行拆卸。这意味着您设置了一次间隔。闭包中的 index const 值为 0,该值永远不会改变。

当您将其更改为在依赖项数组中具有 index 时,现在每次组件呈现时,如果索引更改,它将拆除旧的间隔并开始一个新的间隔。对于其中的每一个,闭包中 index 的值是效果运行时的任何值。所以第一个为 0,第二个为 1,依此类推

请注意,使用第二种方法,每个时间间隔只会消失一次。所以真的,它们更像是超时而不是间隔。如果你愿意,你可以把它改成setTimeout,结果基本一样。


但是对于您的具体情况,还有一种更好的方法:使用 setIndex 的回调版本。与其依赖闭包来知道 index 的值,不如让 react 告诉你 index 的最新值是多少:

const [index, setIndex] = useState(0);
useEffect(() => {
    const interval = setInterval(() => {
        setIndex(prevIndex => {
            (prevIndex > mainImages.length-1) 
              ? console.log("Bigger", prevIndex)
              : console.log("smaller","i="i);
            return prevIndex + 1;
        });
    }, []);
    return () => clearInterval(interval);
}, []);

// If you don't need the logging, then setting the state can be simply:
//    setIndex(prevIndex => prevIndex + 1)