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