React:更新的状态未反映在递归 useCallback 中

Vin*_*rma 5 javascript typescript reactjs redux react-hooks

我正在增加foo一个名为recursively的useCallback钩子。但是,增加的值不会反映在回调中。foo

const { useState, useCallback } = React;

const App = () => {
  const [foo, setFoo] = useState(0);

  const recursiveCallback = useCallback(() => {
    // always logs 0
    console.log(foo);

    // incrementing foo
    setFoo(foo + 1);

    setTimeout(() => {
      // recursive call
      recursiveCallback();
    }, 250);
  }, [foo]);

  return <button onClick={recursiveCallback}>Click Me</button>;
}

ReactDOM.render(<App />,document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

Den*_*ash 5

您在日志和 setter 函数中都存在值闭包,要修复它,您需要使用功能更新和日志记录:foo===0useEffect

const { useState, useCallback, useEffect } = React;

const App = () => {
  const [foo, setFoo] = useState(0);

  const recursiveCallback = useCallback(() => {
    setFoo(prev => prev + 1);

    setTimeout(() => {
      recursiveCallback();
    }, 250);
  }, [foo]);

  useEffect(() => {
    console.log(foo);
  }, [foo]);

  return <button onClick={recursiveCallback}>Click Me</button>;
}

ReactDOM.render( < App/> , document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
Run Code Online (Sandbox Code Playgroud)


Sag*_*gar 2

要访问 foo 的最新值,请尝试更改此行

setFoo(foo + 1);
Run Code Online (Sandbox Code Playgroud)

setFoo((foo) => foo + 1);
Run Code Online (Sandbox Code Playgroud)

另外,foo作为依赖项传递将更新 useCallback 挂钩,因此避免foo从外部访问并使用以下语法

setState((state) => {
  const newState = { ...state }; 
  // Change State here
  return newState; // return new value
})
Run Code Online (Sandbox Code Playgroud)