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

如何区分React Query中initialData与后续获取的完整数据?

区分React Query中initialData与完整请求数据的实现方案

你当前的代码用initialData从localStorage获取了精简的用户数据,但需要区分这部分初始数据和后端返回的完整数据,下面是几种可行的实现方式:

1. 给数据添加自定义标识字段

直接在初始数据里加一个后端不会返回的标记字段,比如isInitialData,这样就能直观区分两种数据:

export const useCurrentUser = () => {
  const enabled = !isGuestUser();

  return useQuery({
    queryKey: ['currentUser'],
    queryFn: async () => {
      const fullUser = await getCurrentUser();
      // 给完整数据加上标记,明确不是初始数据
      return { ...fullUser, isInitialData: false };
    },
    gcTime: Infinity,
    initialData: enabled
      ? // 给初始数据加上专属标记
        { ...(jwtDecode(localStorage.getItem('token') as string) as User), isInitialData: true }
      : { ...({} as User), isInitialData: true },
    enabled,
    refetchOnWindowFocus: false,
  });
};

使用时直接通过data.isInitialData判断即可,TypeScript也能自动识别这个字段的存在。

2. 利用React Query自带的状态字段

React Query返回的结果里有几个状态字段可以辅助判断:

  • isFetching:当正在请求完整数据时为true,请求完成后变为false
  • dataUpdatedAt:初始数据的更新时间是组件挂载时的时间,完整数据返回后这个时间会被更新

示例用法:

const { data, dataUpdatedAt, isFetching } = useCurrentUser();
// 记录初始时间,用来对比判断是否是初始数据
const initialTime = useRef(Date.now());
const isInitialData = dataUpdatedAt === initialTime.current;

如果是React Query v4及以上版本,还可以用isInitialLoading字段,它会在首次请求(包括使用initialData的阶段)完成后变为false,后续缓存命中时不会触发。

针对TypeScript类型的补充处理

你提到用placeholderData会让类型变成User | undefined,而initialData能保持User类型。可以结合上面的标识字段定义联合类型,让TypeScript自动区分数据类型:

// 定义初始数据和完整数据的类型
type InitialUser = User & { isInitialData: true };
type FullUser = User & { isInitialData: false };
type CurrentUser = InitialUser | FullUser;

export const useCurrentUser = () => {
  const enabled = !isGuestUser();

  return useQuery<CurrentUser>({
    queryKey: ['currentUser'],
    queryFn: async () => {
      const fullUser = await getCurrentUser();
      return { ...fullUser, isInitialData: false };
    },
    gcTime: Infinity,
    initialData: enabled
      ? { ...(jwtDecode(localStorage.getItem('token') as string) as User), isInitialData: true }
      : { ...({} as User), isInitialData: true },
    enabled,
    refetchOnWindowFocus: false,
  });
};

这样在使用data时,TypeScript会根据isInitialData的值自动推断数据的具体类型,避免类型歧义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 04:27:23