如何在React中保存并稍后删除调度的异步thunk中的timeoutId

发布于 01-15 03:04 字数 1889 浏览 5 评论 0原文

我有一个问题,我不知道如何解决。

我想在 setTimeout 时间用完时调用刷新令牌端点。 setTimeout 以两种不同的方式调用:

  1. 当用户登录时
  2. 当用户再次进入页面并拥有不记名令牌

时 如果我只是调用 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:

  1. When user logs in
  2. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

残月升风2025-01-22 03:04:19

我知道这是因为 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文