Javascript 我的状态钩子没有像我预期的那样工作

Javascript 我的状态钩子没有像我预期的那样工作,javascript,reactjs,Javascript,Reactjs,我在React中使用了useStatehook,它的行为很奇怪 如果你看下面的例子,我会期望:调用login,成功后调用setRefreshToken(responseToken),然后调用refresh(),它引用setRefreshToken中的refreshToken集合。实际发生的情况是,refreshtToken在refresh()中未定义 我知道setState是异步的,但我以前从未遇到过类似的问题。我错过什么了吗 import React, { createContext, use

我在React中使用了
useState
hook,它的行为很奇怪

如果你看下面的例子,我会期望:调用
login
,成功后调用
setRefreshToken(responseToken)
,然后调用
refresh()
,它引用
setRefreshToken
中的
refreshToken
集合。实际发生的情况是,
refreshtToken
refresh()
中未定义

我知道
setState
是异步的,但我以前从未遇到过类似的问题。我错过什么了吗

import React, { createContext, useState } from "react";
import jwtDecode from "jwt-decode";

const localStorageKey = "ar_refresh_token";

export const AuthContext = createContext();

export function AuthProvider({ tokenUrl, registerUrl, refreshUrl, children }) {
  const [refreshToken, setRefreshToken] = useState(
    window.localStorage.getItem(localStorageKey)
  );

  const [accessToken, setAccessToken] = useState();

  const login = async (userId, password) => {
    const response = await fetch(tokenUrl, {
      method: "POST",
      mode: "cors",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        userId,
        password
      })
    });


    if (response.status === 201) {
      const token = await response.text();
      setRefreshToken(token);
      window.localStorage.setItem(localStorageKey, token);

      await refresh();
    }
  };

  const refresh = async () => {
    const response = await fetch(refreshUrl, {
      method: "POST",
      mode: "cors",
      headers: {
        "Content-Type": "application/json",
        Authorization: `JWT ${refreshToken}`
      }
    });


    if (response.status === 201) {
      const token = await response.text();
      setAccessToken(token);
    }
  };

  return (
    <AuthContext.Provider
      value={{
        refreshToken,
        accessToken,
        login,
        refresh
      }}
    >
      {children}
    </AuthContext.Provider>
  );
}
import React,{createContext,useState}来自“React”;
从“jwt解码”导入jwtDecode;
const localStorageKey=“ar\u refresh\u token”;
export const AuthContext=createContext();
导出函数AuthProvider({tokenUrl,registerUrl,refreshUrl,children}){
常量[refreshToken,setRefreshToken]=useState(
window.localStorage.getItem(localStorageKey)
);
const[accessToken,setAccessToken]=useState();
const login=async(用户ID、密码)=>{
const response=wait fetch(令牌URL{
方法:“张贴”,
模式:“cors”,
标题:{
“内容类型”:“应用程序/json”
},
正文:JSON.stringify({
用户ID,
密码
})
});
如果(response.status==201){
const token=wait response.text();
setRefreshToken(令牌);
setItem(localStorageKey,token);
等待刷新();
}
};
常量刷新=异步()=>{
const response=等待获取(刷新URL{
方法:“张贴”,
模式:“cors”,
标题:{
“内容类型”:“应用程序/json”,
授权:`JWT${refreshToken}`
}
});
如果(response.status==201){
const token=wait response.text();
setAccessToken(令牌);
}
};
返回(

您是对的,在调用
刷新
之前不会重新渲染组件,因此
刷新
中的
刷新令牌
将是默认的

您可以将
login
中的
token
作为参数传递给
refresh
,并使用它,它将按预期工作

const login = async (userId, password) => {
  // ...
  if (response.status === 201) {
    // ...
    await refresh(token);
  }
};

const refresh = async refreshToken => {
  const response = await fetch(refreshUrl, {
    method: "POST",
    mode: "cors",
    headers: {
      "Content-Type": "application/json",
      Authorization: `JWT ${refreshToken}`
    }
  });

  // ...
};
refreshToken
发生更改时,您可以使用自动调用
refresh

...
    if (response.status === 201) {
      const token = await response.text();
      setRefreshToken(token);
      window.localStorage.setItem(localStorageKey, token);

      //await refresh();
    }
...
useEffect(
  () => {
    // your refresh code
  },
  [refreshToken]
)
useffect
中的代码将在第一次渲染时以及
refreshtToken
更改后调用。因此,在每次调用
setrefreshtToken
后,您不需要调用
refresh