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

react-query设置staleTime后onSuccess未触发无法初始化表单怎么办?

问题核心原因

你遇到的是TanStack Query(原React Query)的默认设计行为:onSuccess回调仅在网络请求成功返回新数据时触发,当数据命中staleTime内的缓存、未发起实际网络请求时,onSuccess不会执行。

无需使用useEffect的解决方案


方案1:改造自定义query hook,兼容缓存数据触发回调

你可以修改useGetUserDetailsQuery的内部逻辑,只要拿到有效数据(不管来源是缓存还是新请求)就执行传入的回调,业务组件不需要做任何改动:

import { useRef } from 'react';

export const useGetUserDetailsQuery = (
    onSuccess?: (stateData: GetUserDetailsQueryResp) => void,
): UseQueryResult<GetUserDetailsQueryResp, ErrorResponse> => {
    // 用ref存储上一次已经处理过的数据,避免重复执行回调
    const lastProcessedDataRef = useRef<GetUserDetailsQueryResp | null>(null);
    const queryResult = useGraphqlQuery('get-user-details', GET_USER_DETAILS, {
        staleTime: 600000,
        // 保留原有逻辑,处理网络请求返回的新数据
        onSuccess: (data) => {
            onSuccess?.(data);
            lastProcessedDataRef.current = data;
        },
    });

    // 渲染时判断:存在未处理的缓存数据就直接执行回调
    if (queryResult.data && queryResult.data !== lastProcessedDataRef.current) {
        onSuccess?.(queryResult.data);
        lastProcessedDataRef.current = queryResult.data;
    }

    return queryResult;
};

方案2:使用TanStack Query v5的onData回调

如果你已经升级到TanStack Query v5版本,可以直接把onSuccess替换为新增的onData回调,该回调的设计就是无论数据来源是缓存还是网络请求,只要查询拿到有效数据就会触发:

export const useGetUserDetailsQuery = (
    onData?: (stateData: GetUserDetailsQueryResp) => void,
): UseQueryResult<GetUserDetailsQueryResp, ErrorResponse> => {
    return useGraphqlQuery('get-user-details', GET_USER_DETAILS, {
        staleTime: 600000,
        onData: onData,
    });
};

业务组件直接把setInitalState作为onData参数传入即可,不需要其他改动。


注意事项

不要在业务组件里直接写data && setInitalState(data)这类逻辑,否则会因为组件重复渲染触发多次dispatch,用ref缓存上一次处理的数据可以完全规避这个问题。

内容的提问来源于stack exchange,提问作者Ishan jain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 08:45:00