react -usestate-为什么Settimeout函数没有最新的状态值



最近我正在研究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或用户ducer,但这是正确的还是有其他方法可以使用Usestate解决此问题?

另外,如果有人解释了为什么我们在Settimeout内部获得旧状态

,这真的很有帮助。

沙盒URL -https://codesandbox.io/s/xp540ynomo

这归结为闭合在JavaScript中的工作方式。setTimeout给出的功能将从初始渲染中获取flag变量,因为flag未突变。

您可以将函数作为toggleFlag的参数提供。此函数将获得正确的flag值作为参数,而从此函数返回的内容将替换状态。

示例

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>

给出的setTimeout函数将从_onClick函数中获取flag变量。_onClick函数将创建每个渲染,并"存储" flag变量在此渲染上获得的值。

function App() {
  const [flag, toggleFlag] = useState(false);
  console.log("App thinks that flag is", flag);
  const _onClick = () => {
    console.log("_onClick thinks that flag is", flag);
    toggleFlag(!flag);
    setTimeout(() => {
      console.log("setTimeout thinks that flag is", flag);
    }, 100);
  };
  return (
    <div className="App">
      <button onClick={_onClick}>{flag ? "true" : "false"}</button>
    </div>
  );
}

控制台:

App thinks that flag is false
_onClick thinks that flag is false
App thinks that flag is true
setTimeout thinks that flag is false
_onClick thinks that flag is true
App thinks that flag is false
setTimeout thinks that flag is true

您还可以使用此软件包来解决内部函数中的"旧状态值"。问题:https://github.com/aminadav/reeact-usestateref

相关内容

  • 没有找到相关文章

最新更新