如何通过索引键更新React Query中的已有缓存数据?
React Query 通过索引更新已有记录的正确做法
原代码存在的问题
- 无需调用
getQueriesData(['comments']),setQueryData的回调函数会直接传入当前查询的最新数据 map操作后未返回新数组,导致数据更新不生效- 直接修改原对象
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
相关产品推荐
相关产品推荐

