function useRequest() {
const [accessToken, setAccessToken] = useState(42);
const [refreshToken, setRefreshToken] = useState(7);
const request = async (url) => {
try {
const res = await axios.get(url, { Headers: { Auth: accessToken } });
} catch (error) {
if (error.response.status === 401) {
refresh(() => request(url));
}
}
}
const refresh = async (callback) => {
const res = await axios.get("myserver.com", { params: { refreshToken }});
setAccessToken(res.data.accessToken);
callback()
}
return request;
}
所以我想调用这个api,并在访问令牌过期时刷新它。问题是,当我在刷新函数中设置访问令牌状态时,回调是用旧状态调用的,因为setState是异步的。在其他情况下,我可以使用useEffect,但我不确定在这种情况下该怎么办。
我认为您希望将accessToken
存储在ref
而不是state
中。
官方反应文件:https://reactjs.org/docs/hooks-reference.html#useref
useState
是异步的,因为React假设状态与UI相关,所以状态更新与React渲染生命周期相耦合。
更新ref
是同步的,对于持久化不需要触发UI更新的数据来说是一个很好的选择。
您的代码,但使用useRef
function useRequest() {
const accessTokenRef = useRef(42);
const [refreshToken, setRefreshToken] = useState(7);
const request = async (url) => {
try {
const res = await axios.get(url, { Headers: { Auth: accessTokenRef.current } });
} catch (error) {
if (error.response.status === 401) {
refresh(() => request(url));
}
}
}
const refresh = async (callback) => {
const res = await axios.get("myserver.com", { params: { refreshToken }});
accessTokenRef.current = res.data.accessToken;
callback()
}
return request;
}
如果出于任何原因不想使用useEffect
,另一个选项是将您设置的状态传递给request
函数,这样它就不依赖于外部变量。
const request = async (url, accessToken = 42) => {
try {
const res = await axios.get(url, { Headers: { Auth: accessToken } });
} catch (error) {
if (error.response.status === 401) {
refresh((accessToken) => request(url, accessToken));
}
}
}
const refresh = async (callback) => {
const res = await axios.get("myserver.com");
const { accessToken } = res.data;
setAccessToken(accessToken);
callback(accessToken);
}