React - useState - 为什么setTimeout函数没有最新的状态值?

2023-11-26

最近我正在研究 React Hooks,并遇到了一个问题/疑问?

下面是重现该问题的基本实现,这里我只是切换flag单击按钮时的(状态)变量。

  const [flag, toggleFlag] = useState(false);
  const data = useRef(null);
  data.current = flag;

  const _onClick = () => {
    toggleFlag(!flag);
    // toggleFlag(!data.current); // working

    setTimeout(() => {
      toggleFlag(!flag); // does not have latest value, why ?
      // toggleFlag(!data.current); // working
    }, 2000);
  };

  return (
    <div className="App">
      <button onClick={_onClick}>{flag ? "true" : "false"}</button>
    </div>
  );

我想出了一些其他方法来解决这个问题,例如使用 useRef 或 useReducer,但是这是正确的还是有其他方法可以仅使用 useState 来解决这个问题?

Also, 如果有人解释为什么我们在 setTimeout 中得到旧的状态值,那将会非常有帮助.

沙箱网址 -https://codesandbox.io/s/xp540ynomo


这归结为 JavaScript 中闭包的工作原理。赋予的函数setTimeout将得到flag来自初始渲染的变量,因为flag没有突变。

您可以改为给出一个函数作为参数toggleFlag。该函数将得到正确的flagvalue 作为参数,从该函数返回的内容将替换状态。

Example

const { useState } = React;

function App() {
  const [flag, toggleFlag] = useState(false);

  const _onClick = () => {
    toggleFlag(!flag);

    setTimeout(() => {
      toggleFlag(flag => !flag)
    }, 2000);
  };

  return (
    <div className="App">
      <button onClick={_onClick}>{flag ? "true" : "false"}</button>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React - useState - 为什么setTimeout函数没有最新的状态值? 的相关文章

随机推荐