React 上下文每次使用它时都会返回初始状态 - 尽管 setState
Posted
技术标签:
【中文标题】React 上下文每次使用它时都会返回初始状态 - 尽管 setState【英文标题】:React context returns initial state every time using it - despite setState 【发布时间】:2020-07-03 11:45:57 【问题描述】:我已经创建了这个简单的身份验证组件。
当应用程序刷新并加载 ContextProvider
时,useEffect
方法被触发并设置用户登录。
看看代码
import React, createContext, useState, useContext, useEffect from 'react';
import User from 'utils/User/User';
import useLocale from 'store/LocaleContext';
import tokenKey from 'consts';
const AuthContext = createContext();
const initialState = auth: false, user: null ;
export const AuthContextProvider = ( children ) =>
const [state, setState] = useState(initialState);
const setLanguage = useLocale();
const loginUser = user =>
setLanguage(user.getLanguage());
user.login();
setState( ...state, user: user, auth: true );
setTimeout(() =>
logOutUser();
, 2000);
;
const logOutUser = () =>
console.log(state.user, state); // Output: null, auth: false, user: null
state.user.logout();
setState(initialState);
;
useEffect(() =>
User.Credentials.loginWithToken(localStorage.getItem(tokenKey))
.then(data => data.data)
.then(data =>
if (data.success && data.user)
loginUser(new User(data.user));
)
.catch(err =>
console.log(err);
logOutUser();
);
, []);
return (
<AuthContext.Provider
value=
auth: state.auth,
user: state.user,
loginUser,
logout: logOutUser
>
children
</AuthContext.Provider>
);
;
export default () => useContext(AuthContext);
loginUser
方法正确执行,但我想测试logoutUser
函数。
所以我决定在登录 2 秒后运行 logoutUser
函数,但它读取的是旧状态。
当我登录 state
和 state.user
时,我得到输出:null, auth: false, user: null
。如您所见,它显示为initialState
或状态没有改变。
你能告诉我什么问题和我做错了什么吗?
任何帮助将不胜感激
【问题讨论】:
【参考方案1】:两件事。两者都与 useState 异步有关。
-
您需要使用函数作为传递给 setState 的第一个参数。 React 将使用 at-call-time-current 状态调用它,并期望您返回一个 Object 以合并到状态中。
setState(state => ([...state, user: user, auth: true]));
-
您需要使用 Hook
useEffect()
以确保您在 console.log()
时获得更新版本的状态。
useEffect(() => console.log(state) , [state]);
如果这有帮助,请告诉我!
【讨论】:
我尝试了第一个但得到了相同的结果。注意:当我从标题组件(或其他地方)调用注销功能时,它可以正常工作并记录用户详细信息。但是当我从上下文中调用它时,它会返回initialState
@MalkhaziDartsmelidze:你找到解决方案了吗?以上是关于React 上下文每次使用它时都会返回初始状态 - 尽管 setState的主要内容,如果未能解决你的问题,请参考以下文章
每次更改页面时都会调用 React useEffect (with []) (React Router)
SoundPool 正在加载声音,但每次我播放它时都会显示“样本___ 未准备好”?