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

如何通过索引键更新React Query中的已有缓存数据?

React Query 通过索引更新已有记录的正确做法

原代码存在的问题

  1. 无需调用 getQueriesData(['comments']),setQueryData 的回调函数会直接传入当前查询的最新数据
  2. map 操作后未返回新数组,导致数据更新不生效
  3. 直接修改原对象 r['is_shown'] = false 违反了不可变更新原则,可能导致组件无法触发重新渲染

修正后的实现代码

import { useQuery, useQueryClient } from '@tanstack/react-query';

const CommentsComponent = () => {
  // 必须获取 queryClient 实例
  const queryClient = useQueryClient();

  const {
    data: comments,
    isError,
    isLoading
  } = useQuery({
    queryKey: ['comments'],
    queryFn: async () => {
      const response = await fetch(`https://jsonplaceholder.typicode.com/posts/1/comments`);
      return response.json();
    }
  });

  const onClickHandler = (index) => {
    queryClient.setQueryData(['comments'], (prevComments) => {
      // 不可变更新:返回新数组,每个对象通过浅拷贝生成新实例
      return prevComments.map((comment, i) => ({
        ...comment,
        is_shown: i === index
      }));
    });
  };

  if (isLoading) return <div>加载中...</div>;
  if (isError) return <div>加载失败</div>;

  return (
    <div>
      {comments.map((comment, index) => (
        <div key={comment.id}>
          <h4>{comment.name}</h4>
          <p>{comment.body}</p>
          <button onClick={() => onClickHandler(index)}>
            {comment.is_shown ? '已选中' : '选中这条'}
          </button>
        </div>
      ))}
    </div>
  );
};

export default CommentsComponent;

核心要点说明

  • 调用 setQueryData 时,通过回调函数接收当前查询数据(prevComments),避免直接依赖外部状态
  • 始终遵循不可变更新:用 map 返回新数组,对每个对象做浅拷贝(...comment)后修改字段,确保 React Query 能检测到数据变化并更新组件
  • 简化逻辑:直接用 i === index 赋值 is_shown,无需先统一设为 false 再单独修改目标项

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 21:30:32