使用React Hooks设置状态,在什么情况下,我必须将函数通过以设置状态



这是我的代码:

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打来电话,则不是这种情况。

为什么?

问题是useEffect

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

它是空数组([](。它定义了钩子的依赖性列表。因为它为空,这意味着钩子并不取决于状态或道具的任何值。因此,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>
}

看来,使用回调是从setInterval调用状态的最简单方法。在上面和https://overreacted.io/making-setinterval-declarative-with-react-hooks/

相关内容

  • 没有找到相关文章