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

TanStack Query中useQuery的onSuccess与select选项差异及类型推导问题

TanStack Query useQuery 相关问题解答

1. onSuccess 与 select 选项的区别

  • 核心作用不同
    • select 是数据转换层:专注于对 queryFn 返回的原始数据做同步加工,输出组件实际需要的数据格式,最终 useQuery 返回的 data 就是转换后的值,但缓存中存储的仍是原始数据。
    • onSuccess 是成功回调钩子:用于在请求成功完成后执行副作用逻辑,比如弹出成功提示、更新全局状态、跳转路由等,不参与数据的转换或缓存操作。
  • 缓存交互逻辑不同
    • select 不会修改缓存内的原始数据,同一 Query Key 下的其他组件若未配置 select,获取到的还是原始请求结果。
    • onSuccess 与缓存数据无直接关联,仅作为请求成功后的触发点执行额外操作。
  • 执行时机与返回值
    • select 每次从缓存或新请求中获取数据时都会执行,其返回值会覆盖原始数据作为组件可用的 data。
    • onSuccess 仅在新请求成功完成时触发(从缓存读取数据不会触发),无返回值,仅负责执行副作用。

2. select 选项的类型推导问题

不需要在转换后显式添加类型,TanStack Query 支持通过自动推导或显式泛型指定两种方式获取转换后的类型:

  • 自动推导:只要 select 函数的返回类型明确,TypeScript 会自动将 useQuery 返回的 data 类型识别为转换后的值。示例:
    interface User {
      id: number;
      name: string;
    }
    
    const { data } = useQuery({
      queryKey: ['users'],
      queryFn: () => fetch('/api/users').then(res => res.json() as User[]),
      select: (users) => users.map(user => user.name) // 返回 string[] 类型
    });
    // data 自动推导为 string[]
    
  • 显式指定泛型:如果转换逻辑复杂导致自动推导失效,可通过 useQuery 的泛型参数明确最终数据类型、原始数据类型和错误类型:
    interface User {
      id: number;
      name: string;
    }
    type UserNameList = string[];
    
    const { data } = useQuery<UserNameList, Error, User[]>({
      queryKey: ['users'],
      queryFn: () => fetch('/api/users').then(res => res.json() as User[]),
      select: (users) => users.map(user => user.name)
    });
    // data 类型为 UserNameList
    
  • 特殊情况:若 select 函数存在多分支逻辑导致返回类型模糊,可给 select 函数添加返回类型注解,进一步明确类型,无需手动转换后再额外赋值类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 09:22:16