【问题标题】:Is it possible to get the current length of an array stored in state inside an interval running in useEffect hook?是否可以在 useEffect 挂钩中运行的间隔内获取存储在 state 中的数组的当前长度?
【发布时间】:2019-09-15 06:04:08
【问题描述】:

我有一种情况,我需要在用户的操作(比如说点击)上输出一定数量的元素,每个元素都必须在前一个元素之后出现 500 毫秒。 元素数组存储在状态中,新元素添加到 setInterval 中运行在 useEffect 钩子中。

这是问题所在:在钩子和区间内,我无法访问数组的长度,也不能将其作为依赖项传递,因为它会导致无限循环。但是我必须在已经显示一定数量的元素后停止间隔。

我通过将 setInterval 迭代保留在钩子中找到了解决问题的方法。我想知道这是正确的还是有更好/更惯用的方法。

我在代码沙盒上创建了一个简单的问题示例:https://codesandbox.io/s/xo879wn08z

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    您可以在状态更新程序回调中清除您可以访问数字数组的间隔

    setNumbers(numbers => {
        if (numbers.length === 9) {
          clearInterval(interval);
        }
    
        return [...numbers, Math.random()]
     });
    

    Working demo

    【讨论】:

      【解决方案2】:

      不如使用 setTimeout 来代替 setInterval。您每次都会创建一个新的超时,但前提是长度小于 10。

        useEffect(() => {
          let id;
          if (isCounting && numbers.length < 10) {
            id = setTimeout(() => setNumbers([...numbers, Math.random()]), 500);
          }
          return () => clearTimeout(id);
        }, [isCounting, numbers]);
      

      【讨论】:

      • 这种方式 useEffect 将在每次重新渲染时运行,因为数组总是不相等的。如果我们有一个更复杂的检查,那么在每次重新渲染时运行它可能会很昂贵。它有效,但我不认为这就是我们应该使用的钩子?
      • This way useEffect would run on every re-render since array is always non-equal. 是的,这就是我想要做的。我希望它每次都创建一个新的设置超时,这意味着每次都运行效果。只有当它达到 10 的长度时,它才会停止变化,从而停止运行效果。 I don't think this is how the hooks we're meant to be used 如果这不能满足您的需求,没关系。但我认为每次运行效果正是效果挂钩的使用方式。跳过它们是一种优化。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-16
      • 2020-12-06
      • 1970-01-01
      • 2015-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多