Javascript 反应上下文API不更新存储

Javascript 反应上下文API不更新存储,javascript,reactjs,react-context,Javascript,Reactjs,React Context,我正在处理刷新令牌。我在使用上下文api存储时遇到了一些问题。商店给了我旧的价值。 请查看refreshToken方法,其中有解释错误的注释。我不明白为什么我console.log(store)React会返回旧值而不是新值。 重复,因为下面请我详细描述文本 我正在处理刷新令牌。我在使用上下文api存储时遇到了一些问题。商店给了我旧的价值。 请查看refreshToken方法,其中有解释错误的注释。我不明白为什么我console.log(store)React会返回旧值而不是新值 import

我正在处理刷新令牌。我在使用上下文api存储时遇到了一些问题。商店给了我旧的价值。 请查看refreshToken方法,其中有解释错误的注释。我不明白为什么我console.log(store)React会返回旧值而不是新值。

重复,因为下面请我详细描述文本

我正在处理刷新令牌。我在使用上下文api存储时遇到了一些问题。商店给了我旧的价值。 请查看refreshToken方法,其中有解释错误的注释。我不明白为什么我console.log(store)React会返回旧值而不是新值

import React, { useState, createContext, useEffect } from 'react';
import {MainUrl, ApiUrl} from '../config';
export const StoreContext = createContext();

export const StoreProvider = props => {
    const getToken = () => localStorage.getItem("token");

const initState = () => ({
    token: getToken(),
    isAuth: false,
    userRole: "",
    userName: "",
    userGroupId: null,
    mainUrl: MainUrl,
    apiUrl: ApiUrl,
})

const [store, setStore] = useState(initState());

const getUserInfo = async () => {
    if (getToken()) {
        try {
            const apiConfig = {
                method: "GET",
                headers: {
                "Content-Type": "application/json",
                "Authorization": `Bearer ${store.token}`,
                },
            };

            const response = await fetch(`${store.apiUrl}get-me`, apiConfig);
            const responseJson = await response.json();

            if (response.ok) {
                // Update Context API
                setStore({
                    ...store,
                    userRole: responseJson.role,
                    userName: responseJson.name,
                    userGroupId: responseJson.group_id,
                    isAuth: true,
                })

            } else if(response.status === 401) {
                await refreshToken();
                // Here I want call this function with refreshed token but React gives old token, although I updated token in refreshToken method
                getUserInfo();
            } else {
                throw new Error(`Возникла ошибка во получения информации об пользователе. Ошибка сервера: ${responseJson.error}`);
            }
        } catch (error) {
            console.log(error);
        }
    }
}

const logout = async (routerHistory) => {
    try {
        const apiConfig = {
            method: "GET",
            headers: {
                "Accept": "application/json",
                "Content-Type": "application/json",
                "Authorization": `Bearer ${store.token}`,
            },
        };

        const response = await fetch(`${store.apiUrl}logout`, apiConfig);
        const responseJson = await response.json();

        if (response.ok) {
            // Remove token from localstorage
            localStorage.removeItem("token");
            // Reset Context API store
            setStore(initState());
            // Redirect to login page
            routerHistory.push("/");
        } else if(response.status === 401) {
            await refreshToken();
            logout(routerHistory);
        } else {
            throw new Error(`Возникла ошибка во время выхода. Ошибка сервера: ${responseJson.error}`);
        }
    } catch (error) {
        console.log(error);
    }
}

const refreshToken = async () => {
    try {
        const apiConfig = {
            method: "GET",
            headers: {
                "Accept": "application/json",
                "Authorization": `Bearer ${store.token}`,
            },
        };

        const response = await fetch(`${store.mainUrl}refresh-token`, apiConfig);
        const responseJson = await response.json();

        if (response.ok) {
            // Update token in local storage
            localStorage.setItem("token", responseJson.token);
             // Update Context API
            setStore({
                ...store,
                userRole: 'some new role',
                token: responseJson.token,
            })
            // Here I expect that userRole and token are changed but if I console.log(store) I get old token and null for userRole
            console.log(store);
        }  else {
            throw new Error(`Возникла ошибка во время обновления токена`);
        }
    } catch (error) {
        throw error;
    }
}

useEffect(() => {
    // Get user info
    getUserInfo();
}, [])

return(
    <StoreContext.Provider value={[store, setStore, logout, getUserInfo]}>
        {props.children}
    </StoreContext.Provider>
);
import React,{useState,createContext,useffect}来自'React';
从“../config”导入{MainUrl,ApiUrl};
export const StoreContext=createContext();
export const StoreProvider=props=>{
const getToken=()=>localStorage.getItem(“令牌”);
常量initState=()=>({
标记:getToken(),
伊萨思:错,
用户角色:“”,
用户名:“”,
userGroupId:null,
mainUrl:mainUrl,
apiUrl:apiUrl,
})
const[store,setStore]=useState(initState());
const getUserInfo=async()=>{
if(getToken()){
试一试{
常数apiConfig={
方法:“获取”,
标题:{
“内容类型”:“应用程序/json”,
“授权”:`Bearer${store.token}`,
},
};
const response=wait fetch(`${store.apirl}get me`,apiConfig);
const responseJson=wait response.json();
if(response.ok){
//更新上下文API
固定存储({
…商店,
userRole:responseJson.role,
用户名:responseJson.name,
userGroupId:responseJson.group\u id,
伊萨思:没错,
})
}else if(response.status==401){
等待刷新令牌();
//这里我想用刷新的令牌调用这个函数,但React给出了旧令牌,尽管我在refreshToken方法中更新了令牌
getUserInfo();
}否则{
抛出新的错误(`Böbзbзbбbбbбbбbбbбbбbбbбbбbбbбbбbбbбbбbбbбbбbбbбbб;
}
}捕获(错误){
console.log(错误);
}
}
}
常量注销=异步(路由历史)=>{
试一试{
常数apiConfig={
方法:“获取”,
标题:{
“接受”:“应用程序/json”,
“内容类型”:“应用程序/json”,
“授权”:`Bearer${store.token}`,
},
};
const response=await fetch(`${store.apirl}logout`,apiConfig);
const responseJson=wait response.json();
if(response.ok){
//从本地存储中删除令牌
localStorage.removietem(“令牌”);
//重置上下文API存储
设置存储(initState());
//重定向到登录页面
routerHistory.push(“/”);
}else if(response.status==401){
等待刷新令牌();
注销(路由器历史记录);
}否则{
抛出新的错误(`böbзbзbбbбbбbбbбbбbбbбbбbбbбbбbбa;
}
}捕获(错误){
console.log(错误);
}
}
常量刷新令牌=异步()=>{
试一试{
常数apiConfig={
方法:“获取”,
标题:{
“接受”:“应用程序/json”,
“授权”:`Bearer${store.token}`,
},
};
const response=wait fetch(`${store.mainUrl}刷新令牌`,apiConfig);
const responseJson=wait response.json();
if(response.ok){
//更新本地存储中的令牌
setItem(“token”,responseJson.token);
//更新上下文API
固定存储({
…商店,
userRole:“某个新角色”,
令牌:responseJson.token,
})
//在这里,我希望userRole和token被更改,但如果我使用console.log(store),我会得到userRole的旧token和null
控制台日志(存储);
}否则{
抛出新的错误(`Сззббббббббббббббббб1073;
}
}捕获(错误){
投掷误差;
}
}
useffect(()=>{
//获取用户信息
getUserInfo();
}, [])
返回(
{props.children}
);
}来自
useState()
钩子的
setStore()
函数是一个异步函数,因此您不会立即从
console.log()
调用(就在
setStore()
之后)获取更新的值

此外,没有提供回调函数作为
setStore()
函数的第二个参数,您可以在其中记录更新的状态

useEffect(() => {
    console.log(store);
})
但是,您可以将
console.log(store)
调用移动到
useffect()
hook中,该钩子在每次状态更新后都会触发,并确保获得更新的状态

useEffect(() => {
    console.log(store);
})
所以,就问题的标题“React Context API not Updated store”而言,它实际上是在更新。只是在更新之前您正在记录它

希望这有帮助

来自
useState()
钩子的
setStore()
函数是一个异步函数,因此您不会立即从
控制台.log()
调用(就在
setStore()
之后)获取更新的值

此外,没有提供回调函数作为
setStore()
函数的第二个参数,您可以在其中记录更新的状态

useEffect(() => {
    console.log(store);
})
但是,您可以在
useffect()
hook中移动
console.log(store)
调用