gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:29:39 25 4
gpt4 key购买 nike

最近我在研究 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 来解决这个问题?

此外,如果有人能解释为什么我们在 setTimeout 中获取旧状态值,那将非常有帮助。

沙盒网址 - 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>

关于javascript - React - useState - 为什么 setTimeout 函数没有最新的状态值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55198517/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com