React-UseState-为什么setTimeout函数没有最新状态值? [英] React - useState - why setTimeout function does not have latest state value?
问题描述
最近我正在研究React Hooks,并陷入一个问题/疑问?
Recently I was working on React Hooks and got stuck with one problem/doubt?
下面是重现此问题的基本实现,在这里,我只是单击按钮即可切换flag
(状态)变量.
Below is a basic implementation to reproduce the issue, Here I'm just toggling flag
(a state) variable on click of the button.
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解决此问题?
I figured out some other way to overcome this problem like using useRef or useReducer, but is this correct or is there any other way to solve this with useState only?
此外,如果有人解释为什么我们会在setTimeout中获得旧的状态值,这将非常有帮助.
沙盒网址- https://codesandbox.io/s/xp540ynomo
推荐答案
这归结为闭包在JavaScript中的工作方式.由于未更改flag
,赋予setTimeout
的函数将从初始渲染中获取flag
变量.
This boils down to how closures work in JavaScript. The function given to setTimeout
will get the flag
variable from the initial render, since flag
is not mutated.
您可以给toggleFlag
提供一个函数作为参数.此函数将获取正确的flag
值作为参数,并且此函数返回的内容将替换状态.
You could instead give a function as argument to toggleFlag
. This function will get the correct flag
value as argument, and what is returned from this function is what will replace the state.
示例
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>
这篇关于React-UseState-为什么setTimeout函数没有最新状态值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!