Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React上下文每次使用时都返回初始状态-尽管设置为state_Javascript_Reactjs_React Hooks_React Context - Fatal编程技术网

Javascript React上下文每次使用时都返回初始状态-尽管设置为state

Javascript React上下文每次使用时都返回初始状态-尽管设置为state,javascript,reactjs,react-hooks,react-context,Javascript,Reactjs,React Hooks,React Context,我创建了这个简单的身份验证组件。 当应用程序刷新并加载ContextProvider时,将触发useffect方法并设置用户登录 查看代码 import React,{createContext,useState,useContext,useffect}来自“React”; 从“utils/User/User”导入用户; 从“store/LocaleContext”导入useLocale; 从“consts”导入{tokenKey}; const AuthContext=createContex

我创建了这个简单的身份验证组件。 当应用程序刷新并加载
ContextProvider
时,将触发
useffect
方法并设置用户登录

查看代码

import React,{createContext,useState,useContext,useffect}来自“React”;
从“utils/User/User”导入用户;
从“store/LocaleContext”导入useLocale;
从“consts”导入{tokenKey};
const AuthContext=createContext();
const initialState={auth:false,user:null};
导出常量AuthContextProvider=({children})=>{
常量[状态,设置状态]=使用状态(初始状态);
const{setLanguage}=useLocale();
const login用户=用户=>{
setLanguage(user.getLanguage());
user.login();
setState({…state,user:user,auth:true});
设置超时(()=>{
logOutUser();
}, 2000);
};
const logOutUser=()=>{
console.log(state.user,state);//输出:null,{auth:false,user:null}
state.user.logout();
设置状态(初始状态);
};
useffect(()=>{
User.Credentials.loginWithToken(localStorage.getItem(tokenKey))
.然后(data=>data.data)
。然后(数据=>{
if(data.success&&data.user){
登录用户(新用户(data.User));
}
})
.catch(错误=>{
控制台日志(err);
logOutUser();
});
}, []);
返回(
{儿童}
);
};
导出默认值()=>useContext(AuthContext);
loginUser
方法正确执行,但我想测试
logoutUser
函数。 所以我决定在登录2秒钟后运行
logoutUser
函数,但它读取的是旧状态

当我记录
state
state.user
时,我得到输出:
null,{auth:false,user:null}
。因此,正如您所看到的,它读取的是
initialState
,或者状态没有改变

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


任何帮助都将受到感激

两件事。两者都与useState异步相关

  • 您需要使用函数作为传递给setState的第一个参数。React将在调用时使用当前状态调用它,并期望您返回一个要合并到状态中的对象
  • setState(state=>([…state,user:user,auth:true])

  • 您需要使用钩子
    useffect()
    ,以确保在
    console.log()
    时获得状态的更新版本
  • useffect(()=>{console.log(state)},[state])


    让我知道这是否有帮助

    我试了第一个,但得到了同样的结果。注意:当我从header组件(或其他地方)调用logout函数时,它工作正常并记录用户详细信息。但是当我从上下文调用它时,它返回
    初始状态
    @MalkhaziDartsmelidze:你找到解决方案了吗?
    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);