reactjs - useContext 调用阻止后续 useState 更新
问题描述
我有一些路线的提供者包装
<Provider>
<Route path={ROUTES.SIGNING}><SignIn /></Route>
<PrivateRoute path={ROUTES.PRIVATE}><Private /></PrivateRoute>
</Provider>
这Provider
只是一个包装器userContext
import React, { useState } from 'react';
import UserContext from '../../user.context';
let defaultUser = '';
try {
defaultUser = JSON.parse(localStorage.getItem('profile'));
} catch {
defaultUser = '';
}
function Provider(props) {
const [user, setUser] = useState(defaultUser);
return <UserContext.Provider value={{ user, setUser }}>{props.children}</UserContext.Provider>
}
export default Provider;
我的<SignIn />
组件等待来自数据服务的响应,然后 1. 尝试从 userContext 更新设置器,然后尝试更新它自己的 useState 函数。它似乎永远不会执行内部 useState 函数。
function SignIn() {
const { user, setUser } = useContext(UserContext);
const [formStatus, setFormStatus] = useState();
async function handleSubmit(e) {
e.preventDefault();
const result = await signin(credentials);
setUser({ isInternal: result.isInternal, clientId: result.clientId });
setFormStatus((curStatus) => ({ ...curStatus, state: FORMSTATUS.COMPLETED }));
}
为什么 setStatus 似乎永远不会触发?我认为这是因为 setUser 更新了 Provider,它是比子登录页面更高级别的组件。任何帮助都会很棒
解决方案
你有一个竞争条件。要解决此问题,您需要指定本地状态更新应在上下文状态更新之前完成。
解决方案:
- 使用React 的函数形式来设置本地状态。
- 然后在功能集状态调用中调用您的上下文状态更新。
这样,您在更新上下文之前就知道本地状态已完成。
推荐阅读
- html - 电子邮件开发页脚表小于正文表
- javafx - 右键单击 CodeArea 获取字符索引
- asynchronous - 当我尝试同时管理 Cisco 设备时,Asyncio 无法按预期工作
- c++ - 使用一个参数的模板函数时出错(与 2 一起使用)
- python - 图像多分类模型拟合期间遇到错误:语法错误:位置参数跟随关键字参数
- html - 如何阻止样式更改应用于具有递归组件的所有内容?
- linux - nginx启动创建孤儿进程
- cypress - 检查 cypress 中的动态元素
- blockchain - 无法使用 tessera 与仲裁节点发送交易
- javascript - Google.Script.Run - 不以第二种形式初始化