如何在React Query的useInfiniteQuery中添加新数据至数组开头?
如何用queryClient.setQueryData给useInfiniteQuery的缓存添加新帖子到开头
当然可以用queryClient.setQueryData实现这个需求,不过得注意useInfiniteQuery的缓存结构和普通useQuery不一样——它返回的data是包含pages和pageParams的对象,其中pages是每次请求返回结果组成的数组。直接修改data(比如data.unshift)不会触发缓存更新和组件重渲染,必须通过queryClient来操作缓存。
具体实现步骤
- 通过
useQueryClient获取queryClient实例 - 在添加帖子的逻辑里,先调用API创建新帖子,再更新缓存
- 按照
useInfiniteQuery的缓存结构修改数据,把新帖子插入到pages数组的第一个元素开头
完整代码示例
import { useInfiniteQuery, useQueryClient } from '@tanstack/react-query'; // ... 其他组件代码 const queryClient = useQueryClient(); const { status, data, error, isFetching, isFetchingNextPage, fetchNextPage, hasNextPage } = useInfiniteQuery( ['posts'], async ({ pageParam = '' }) => { const res = await postAPI.getPost(as, pageParam, PAGE_LIMIT); return res; }, { getNextPageParam: (lastPage) => lastPage.length && lastPage.length >= 5 ? lastPage[lastPage.length - 1]?.id : undefined, }, ); const handleAddNewPost = async () => { // 1. 调用API添加新帖子,获取返回的新帖子数据 const newPost = await postAPI.addPost({ /* 新帖子的参数 */ }); // 2. 更新useInfiniteQuery的缓存 queryClient.setQueryData(['posts'], (existingCacheData) => { // 如果缓存里还没有数据,直接创建新的pages结构 if (!existingCacheData) { return { pages: [[newPost]], pageParams: [''] }; } // 复制现有pages数组,避免直接修改原缓存数据 const updatedPages = [...existingCacheData.pages]; // 把新帖子插入到第一个page的开头 updatedPages[0] = [newPost, ...updatedPages[0]]; // 返回更新后的缓存结构 return { ...existingCacheData, pages: updatedPages }; }); }; // ... 其他组件代码 <button onClick={handleAddNewPost}>Add new data</button>
关键说明
useInfiniteQuery的缓存结构是{ pages: T[], pageParams: Param[] },必须严格按照这个结构更新,否则会导致后续无限滚动逻辑出错- 更新缓存时要复制原数据(比如
[...existingCacheData.pages]),不能直接修改原缓存对象,保证数据不可变性 - 建议在API调用成功后再更新缓存,确保后端数据和前端缓存一致
内容的提问来源于stack exchange,提问作者Epple
相关产品推荐
相关产品推荐

