最近我正在研究 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
。该函数将得到正确的flag
value 作为参数,从该函数返回的内容将替换状态。
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(使用前将#替换为@)