最近我正在研究React Hooks,陷入一个问题/疑问?
下面是重现该问题的基本实现,在这里,我只是flag在单击按钮时切换(状态)变量。
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中获得旧的state值 , 这将非常有帮助 。
沙盒网址-https: //codesandbox.io/s/xp540ynomo
这归结为闭包在JavaScript中的工作方式。给定的函数将从初始渲染中setTimeout获取flag变量,因为flag它不会发生突变。
setTimeout
您可以改为将函数作为参数toggleFlag。此函数将获取正确的flag值作为参数,并且此函数返回的值将替换状态。
toggleFlag
例
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>