javascript - 在 useEffect 中反应 setTimeout 和 setState
问题描述
我有这段代码,我的问题是为什么在我的答案函数中我得到了初始状态。如何以正确的方式设置状态以在 setTimeout 函数的回调中获得正确的状态?
const App = () => {
const [state, setState] = useState({
name: "",
password: "",
});
useEffect(() => {
setState({ ...state, password: "hello" });
setTimeout(answer, 1000);
}, []);
const answer = () => {
console.log(state);
// we get initial State
};
return <div className="App"></div>;
};
解决方案
原因是关闭。
answer
函数将始终记录调用时关闭的函数state
的值。setTimeout()
在您的代码中,由于setTimeout()
在state
包含具有空值的对象时调用函数,answer
因此函数会记录该值,而不是记录更新的值。
要记录状态的最新值,您可以使用useRef()挂钩。这个钩子返回一个对象,它包含一个名为的属性current
,这个属性的值是传递给的参数useRef()
。
function App() {
const [state, setState] = React.useState({
name: "",
password: "",
});
const stateRef = React.useRef(state);
React.useEffect(() => {
stateRef.current = { ...stateRef.current, password: 'hello'};
setState(stateRef.current);
setTimeout(answer, 1000);
}, []);
const answer = () => {
console.log(stateRef.current);
};
return <div></div>;
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
推荐阅读
- sqlite - 同时进行多个 SELECT 查询
- ios - 具有自定义单元格和多节数组数据的 Swift UITableView
- angular - 动态更改名称
元素 - r - 为什么示例函数给我一个错误
- servicestack-openapi - OpenAPI 在 ServiceStack .NET Core 中引发异常 - Swagger 2.0 不支持空类型
- java - 如何将 MapStruct 用于不同的数据类型?
- cassandra - cassandra 中 max_schema_agreement_wait 的最佳值应该是多少,默认为 10
- laravel - 本地域的 SSL
- elasticsearch - 当 JSON 中缺少键值对时,Logstash "add_field" 将 "%{...}" 保存为值
- anaconda - Conda:为每个环境选择下载包的位置