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

如何解析TanStack Query获取的数据并缓存已解析结果?

TanStack Query 数据转换与缓存优化方案

问题背景

我正在学习TanStack Query(原React Query),已经实现了基础的数据获取功能,但想优化数据转换逻辑以充分利用缓存特性。目前我在组件的JSX中通过convertDataToTasks函数解析API返回的数据,这种方式不够优雅,而且希望把已解析后的Task格式数据直接存入Query缓存,因为外部API返回的内容格式和我需要的Task结构不一致。

解决方案

核心思路是把数据转换逻辑移到Query的queryFn内部,让TanStack Query缓存直接存储转换后的标准化数据,避免组件重复执行转换操作,同时最大化利用缓存特性。

1. 修改Query函数,内置数据转换

直接在queryFn中完成原始数据到Task类型的转换,确保缓存的是最终需要的数据结构:

import { useQuery } from "@tanstack/react-query"

// 修正类型定义语法错误,明确Task结构
type Task = {
  id: number,
  name: string
}

// 简化转换函数,用map替代forEach更高效简洁
function convertDataToTasks(data: any[]): Task[] {
  return data.map(item => ({ 
    id: item.id, 
    name: item.title 
  }))
}

export function toDosQuery() {
  return useQuery({
    queryKey: ['todos'],
    queryFn: async (): Promise<Task[]> => {
      const response = await fetch('https://jsonplaceholder.typicode.com/todos')
      const rawData = await response.json()
      // 请求完成后立即转换数据,缓存结果
      return convertDataToTasks(rawData)
    },
  })
}

2. 简化组件渲染逻辑

组件现在可以直接使用缓存中的转换后数据,无需再调用转换函数:

export function SidebarTasksList() {
  const { status, data, error, isFetching } = toDosQuery()
  
  return (
    <section>
      {status === 'pending' ? (
        'Loading...'
      ) : status === 'error' ? (
        <span>Error: {error.message}</span>
      ) : (
        // 直接使用缓存好的Task数组
        data.map(task => (
          <TaskLabel task={task} key={task.id}/>
        ))
      )}
      <span>{isFetching ? "Fetching new data" : ""}</span>
    </section>
  )
}

优化收益

  • 缓存复用:所有调用toDosQuery的组件都会直接拿到标准化的Task数据,无需重复执行转换逻辑
  • 性能提升:避免组件每次渲染都重复转换数据
  • 类型安全:明确queryFn的返回类型为Task[],消除any类型带来的潜在问题
  • 代码整洁:数据转换逻辑集中在Query层,组件只负责渲染逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 01:40:18