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

React Query如何利用缓存的帖子数据按ID查询?

问题分析与解决

核心问题

  1. 接口返回数据结构处理错误:JSONPlaceholder的/posts接口直接返回帖子数组,并非{ data: [...] }格式,你在onSuccess里用data?.data.map会导致循环不执行,根本没把单帖数据写入缓存。
  2. 缓存键不统一:自定义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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:39:17