React上下文每次使用它时都会返回初始状态——尽管有setState



我创建了这个简单的身份验证组件。当刷新应用程序并加载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函数,但它读取的是旧状态。

当我记录statestate.user时,我得到输出:null, {auth: false, user: null}。所以,正如您所看到的,它读取initialState或状态不变。

你能告诉我出了什么问题,我做错了什么吗?

任何帮助都将被视为

两件事。两者都与异步的useState有关。

  1. 您需要使用一个函数作为传递给setState的第一个参数。React将在调用时使用当前状态调用它,并期望您返回一个Object以合并到状态中

setState(state => ([...state, user: user, auth: true]));

  1. 您需要使用HookuseEffect()来确保在console.log()时获得状态的更新版本

useEffect(() => { console.log(state) }, [state]);

如果这有帮助,请告诉我!

最新更新