如何在React中保存并稍后删除调度的异步thunk中的timeoutId
我有一个问题,我不知道如何解决。
我想在 setTimeout 时间用完时调用刷新令牌端点。 setTimeout 以两种不同的方式调用:
- 当用户登录时
- 当用户再次进入页面并拥有不记名令牌
时 如果我只是调用 setTimeout 而不删除前一个,用户可以登录、退出并再次登录,并且它会发送请求到创建的每个 setTimeout 的刷新令牌端点(在本例中为 2 个请求)。
我想要做的是保存创建的 setTimeout,如果用户决定注销然后再次登录,我们删除 setTimeout 并创建一个新的。但是,当我使用 useState 存储 timeoutId 时,我收到 Invalid hook call 错误。
我的代码如下所示:
storageActions.ts
export function setRefreshTokenTimeout(bearerToken: string, refreshToken: string) {
removeRefreshTokenTimeout();
var decodedBearerToken: any = jwt_decode(bearerToken);
let remainingDuration = calculateRemainingTime(decodedBearerToken.exp * 1000);
remainingDuration = 10000;
const refreshTokens = setTimeout(() => store.dispatch(refreshTokensThunk({ refreshToken })), remainingDuration);
setRefreshTokensTimeout(refreshTokens);
}
export function removeRefreshTokenTimeout() {
if (refreshTokensTimeout) {
clearTimeout(refreshTokensTimeout);
setRefreshTokensTimeout(undefined);
}
}
authActions.ts
export const userLoginThunk = createAsyncThunk<UserLoginResponse, UserLoginRequest>(
"auth/user-login",
async (request, thunkAPI) => {
let response = await AuthServiceUserLogin(request);
setUserLocalStorageData(response.data);
setRefreshTokenTimeout(response.data.bearerToken, response.data.refreshToken);
return response.data;
}
);
export const authUserThunk = createAsyncThunk("auth/authUser", async thunkAPI => {
await AuthServiceAuthUser();
const userStorage = getUserLocalStorageData();
if (userStorage?.data?.bearerToken) {
setRefreshTokenTimeout(userStorage.data.bearerToken, userStorage.data.refreshToken);
}
});
所有这些都在调度的 createAsyncThunk 内调用。有什么办法可以解决这个问题吗?
I have a problem that I don't know how to fix.
I want to call refresh-token endpoint when setTimeout time runs out. setTimeout is called in 2 different ways:
- When user logs in
- When user enters a page again and has bearer token
If I just called setTimeout without deleting the previous one, a user could log in and out and log in again and it would send a request to the refresh-token endpoint for every setTimeout that was created (in this case, 2 requests).
What I want to do is save the setTimeout that was created and if user decides to log out and then log in again, we delete setTimeout and create a new one. However, when I store my timeoutId with useState, I get Invalid hook call error.
This is how my code looks like:
storageActions.ts
export function setRefreshTokenTimeout(bearerToken: string, refreshToken: string) {
removeRefreshTokenTimeout();
var decodedBearerToken: any = jwt_decode(bearerToken);
let remainingDuration = calculateRemainingTime(decodedBearerToken.exp * 1000);
remainingDuration = 10000;
const refreshTokens = setTimeout(() => store.dispatch(refreshTokensThunk({ refreshToken })), remainingDuration);
setRefreshTokensTimeout(refreshTokens);
}
export function removeRefreshTokenTimeout() {
if (refreshTokensTimeout) {
clearTimeout(refreshTokensTimeout);
setRefreshTokensTimeout(undefined);
}
}
authActions.ts
export const userLoginThunk = createAsyncThunk<UserLoginResponse, UserLoginRequest>(
"auth/user-login",
async (request, thunkAPI) => {
let response = await AuthServiceUserLogin(request);
setUserLocalStorageData(response.data);
setRefreshTokenTimeout(response.data.bearerToken, response.data.refreshToken);
return response.data;
}
);
export const authUserThunk = createAsyncThunk("auth/authUser", async thunkAPI => {
await AuthServiceAuthUser();
const userStorage = getUserLocalStorageData();
if (userStorage?.data?.bearerToken) {
setRefreshTokenTimeout(userStorage.data.bearerToken, userStorage.data.refreshToken);
}
});
All of these are called inside a createAsyncThunk that is dispatched. Is there any way to solve this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

我知道这是因为 useState 钩子,但我认为只能使用 useState 或 useRef 等钩子来保存状态。
我刚刚发现这个规则只适用于 React 组件。
storageActions.ts
不是组件,因此我可以使用一个简单的变量来保存我的 timeoutId。我测试了它并且它有效。
I knew this was because of useState hook, but I thought that you can only save states with hooks like useState or useRef.
I just figured out that this rule only refers to React components.
storageActions.ts
isn't a component, therefore I can use a simple variable to save my timeoutId.I tested it and it works.