You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RTK Query createAPI自动重取失效WeatherKit Token未触发问题咨询

解决RTK Query中WeatherKit Token自动重取的问题

问题分析

你遇到的forceRefetch未触发的核心原因是对它的工作机制理解有误:

  • forceRefetch不会主动后台轮询检查Token过期,它仅在组件挂载/重新挂载、查询参数变化、手动调用refetch时,且已有缓存数据的前提下,才会执行判断是否需要重取。
  • 首次挂载时如果没有缓存数据,endpointState.data为undefined,此时forceRefetch的判断逻辑会直接返回false(或报错),自然不会触发。

你的登录时通过invalidatesTags触发重取的逻辑是正确的,这部分能正常工作;但Token过期自动重取的需求,需要结合定时器触发refetch来配合forceRefetch完成。

解决方案

1. 修正forceRefetch的判断逻辑

先处理data不存在的情况,避免报错或误判:

export const generalApi = createApi({
    reducerPath: 'api',
    tagTypes: [ 'settings' ],
    baseQuery: fetchBaseQuery({
        baseUrl: 'https://api.myserver.com/v1/',
        prepareHeaders: (headers, { getState })=> {
            const token = getState().session.token;
            if (token) {
                headers.set('authorization', `Bearer ${token}`);
            }
            return headers;
        }
    }),
    endpoints: (builder)=>({
        getWeatherKitToken: builder.query({
            query: ()=> 'getWeatherKitToken',
            forceRefetch: ({ endpointState })=> {
                console.log('checking for refetch');
                // 仅当缓存存在且Token已过期时返回true
                return endpointState.data?.expires < Date.now() ?? false;
            },
            // 组件挂载时若Token已过期,自动触发重取
            refetchOnMountOrArgChange: (_, __, endpointState) => {
                return endpointState.data?.expires < Date.now() ?? false;
            },
            providesTags: [ 'settings' ]
        }),
        login: builder.mutation({
            query: (body)=>({
                url: 'login',
                method: 'POST',
                body: body
            }),
            invalidatesTags: [ 'settings' ]
        }),
    }),
});

2. 添加定时触发重取的逻辑

在使用useGetWeatherKitTokenQuery的组件中,通过useEffect监听Token的过期时间,提前触发重取:

const { data, refetch } = useGetWeatherKitTokenQuery();

useEffect(() => {
  if (!data) return;

  // 提前30秒触发重取,避免Token过期后才请求
  const timeUntilRefetch = data.expires - Date.now() - 30000;
  if (timeUntilRefetch <= 0) {
    refetch();
    return;
  }

  const timer = setTimeout(() => {
    refetch();
  }, timeUntilRefetch);

  // 组件卸载时清理定时器
  return () => clearTimeout(timer);
}, [data, refetch]);

3. 确认登录场景的重取逻辑

你已通过login mutation的invalidatesTags: ['settings']实现了登录后自动重取Token,这部分无需修改,会在登录成功后自动触发getWeatherKitToken的查询。

补充说明

  • 若你的应用存在多组件使用该Token的场景,建议将定时器逻辑封装到自定义Hook中,避免重复代码。
  • 不要依赖forceRefetch实现后台自动检查,RTK Query的设计初衷是配合组件生命周期或手动触发来管理缓存,定时任务需要自己实现。

内容的提问来源于stack exchange,提问作者Tim Nikischin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 03:53:26