【问题标题】:With react hooks set state, in what cases I have to pass a function to set state?使用反应钩子设置状态,在什么情况下我必须传递一个函数来设置状态?
【发布时间】:2019-06-27 21:24:16
【问题描述】:

这是我的代码:

function Tiker() {
  var [count, setCount] = useState(0);

  useEffect(() => {
    var timerID = setInterval(_=>
      setCount(count=>count+1)//setCount(count+1) wont work
    , 1000);

    return function cleanup() {
      clearInterval(timerID);
    };
  }, []);
  return <div>
      this is ticker   
      <button onClick={() => 
        setCount(count + 1)//setCount(count+1) does work
      }>up </button>
      {count}
      </div>
}

通过反复试验,我发现如果我在 setinterval 回调中使用 setCount,我必须将回调传递给设置状态,而不仅仅是值。

如果我从 onclick 调用,情况并非如此。

这是为什么呢?

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    问题是useEffect的第二个参数

    useEffect(() => {
        var timerID = setInterval(_=>
            setCount(count=>count+1)//setCount(count+1) wont work
        , 1000);
    
        return function cleanup() {
            clearInterval(timerID);
        };
    }, []);
    

    它是空数组([])。它为钩子定义了list of dependencies。因为它是空的,这意味着钩子不依赖于任何状态或道具的值。所以count 变量在第一次调用useEffect 时被消耗,然后保持陈旧。

    要更正此问题,您应该完全删除 useEffect 的第二个参数或使数组包含 [count]

    回调正在工作,因为它接收先前的计数值作为第一个参数。

    所以正确的代码看起来像

    function Tiker() {
        var [count, setCount] = useState(0);
    
        useEffect(() => {
            var timerID = setInterval(_=>
                setCount(count + 1)
            , 1000);
    
            return function cleanup() {
                clearInterval(timerID);
            };
        }, [count]);  // Put variable that useHook depends on
    
        return <div>
            this is ticker   
            <button onClick={() => 
                setCount(count + 1) //setCount(count+1) does work
            }>up </button>
            {count}
        </div>
    }
    

    【讨论】:

    • 我使用空数组的原因是告诉 react 在挂载/卸载周期中只调用一次 setinterval 并清除间隔。 (我遵循了这个建议:stackoverflow.com/questions/53395147/…)。当我向该数组添加计数时,会在每秒发生的每次更新组件时调用函数
    • 这种情况下,您应该像之前那样在setCount 中使用回调。
    【解决方案2】:

    从 setInterval 调用时,使用回调似乎是更改状态的最简单方法。从上面的 Frodor 评论和https://overreacted.io/making-setinterval-declarative-with-react-hooks/

    可以看出

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-30
      • 1970-01-01
      • 2020-03-19
      • 2020-04-01
      • 2021-08-02
      • 1970-01-01
      • 2021-12-18
      相关资源
      最近更新 更多