React Query如何利用缓存的帖子数据按ID查询?
问题分析与解决
核心问题
- 接口返回数据结构处理错误:JSONPlaceholder的
/posts接口直接返回帖子数组,并非{ data: [...] }格式,你在onSuccess里用data?.data.map会导致循环不执行,根本没把单帖数据写入缓存。 - 缓存键不统一:自定义Hook查询单帖用的缓存键是
["post", id](单数),但你设置缓存用的是["posts", id](复数),组件读取也用的是复数键,即使缓存写入成功,Hook也读不到对应数据。
修正后的代码
1. 获取所有帖子的代码(修正数据结构处理)
const { data: posts } = useQuery(["posts"], service.getPosts, { enabled: true, cacheTime: Infinity, onSuccess: (data) => { console.log("DATA", data); // JSONPlaceholder返回直接是数组,无需取data属性 data?.map((post: any) => { queryClient.setQueryData(["posts", post.id], post); }); }, });
2. 自定义Hook(统一缓存键,优先读缓存)
export const useGetPostById = (id: any) => { const service = getQueryService(); const queryClient = useQueryClient(); const { data: post } = useQuery(["posts", id], () => { return service.getPostById(id); }, { // 先从全局帖子缓存里找对应id的数据,没有再发请求 initialData: () => { return queryClient.getQueryData(["posts"])?.find((p: any) => p.id === id); } }); return { post }; };
3. 组件中读取缓存数据
注意确保id是数值类型(JSONPlaceholder的帖子ID为数字,若从路由等地方获取的是字符串需转换):
const postId = Number(id); const targetPost = queryClient.getQueryData(["posts", postId]); console.log(targetPost, "TARGET POST");
额外说明
- 如果你的
service.getPosts封装了统一响应格式(比如返回{ data: 数组 }),那data?.data.map是正确的,否则必须调整为直接遍历data。 - 统一缓存键的命名规则,避免单数/复数混用导致的匹配失败。
内容的提问来源于stack exchange,提问作者tryingToBeBetter
相关产品推荐
相关产品推荐

