如何解析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
相关产品推荐
相关产品推荐

