[英]How can I call a callback that depends on an updated state in react?
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;
}
So I want to call this api and refresh the access token if it expires.所以我想调用这个 api 并在它过期时刷新访问令牌。 Problem is, when I set the access token state in the refresh function, the callback is called with the old state because setState is async.
问题是,当我在刷新 function 中设置访问令牌 state 时,使用旧的 state 调用回调,因为 setState 是异步的。 In other contexts, I could just use useEffect but i'm not sure what to do in this case.
在其他情况下,我可以只使用 useEffect 但我不确定在这种情况下该怎么做。
If you don't want to use useEffect
for whatever reason, another option would be to pass the state you set to the request
function, so that it doesn't depend on external variables.如果您出于某种原因不想使用
useEffect
,另一种选择是将您设置的 state 传递给request
function,以便它不依赖于外部变量。
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);
}
I think you want to store accessToken
in a ref
instead of in state
.我认为您想将
accessToken
存储在ref
中而不是state
中。
Official react documentation: https://reactjs.org/docs/hooks-reference.html#useref官方反应文档: https://reactjs.org/docs/hooks-reference.html#useref
useState
is async because React assumes state is related to the UI, so state updates are coupled to the React render lifecycle. useState
是异步的,因为 React 假设 state 与 UI 相关,因此 state 更新与 React 渲染生命周期相耦合。
Updating the ref
is synchronous, and is a good option for persisting data that doesn't need to trigger UI updates.更新
ref
是同步的,对于不需要触发 UI 更新的持久化数据来说是一个不错的选择。
Your code, but using useRef
您的代码,但使用
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.