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

如何在React Query中通过更新缓存避免额外网络请求?

用React Query的setQueryData直接更新缓存,避免额外GET请求

我在React 18项目中使用React Query,当前在执行PUT数据变更请求后,调用queryClient.invalidateQueries({ queryKey: ['anecdotes'] })会触发额外的GET请求重新拉取数据。我希望通过queryClient.setQueryData直接更新缓存,跳过这次不必要的网络请求,该如何实现?

实现步骤

  • 接收服务器返回的更新后数据:useMutation的onSuccess回调会接收服务器返回的更新完成后的完整数据,用这个数据更新缓存比前端自行计算更可靠。
  • 精准更新缓存条目:通过queryClient.setQueryData获取当前['anecdotes']的缓存数据,遍历找到对应ID的条目并替换,返回更新后的数组作为新缓存值。

修改后的代码

App.jsx

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { getAnecdotes, updateAnecdote } from './requests';
import AnecdoteForm from './components/AnecdoteForm';
import Notification from './components/Notification';

const App = () => {
  const queryClient = useQueryClient();
  
  const updateAnecdoteMutation = useMutation({
    mutationFn: updateAnecdote,
    // 接收服务器返回的更新后数据,直接更新缓存
    onSuccess: (updatedAnecdote) => {
      queryClient.setQueryData(['anecdotes'], (oldData) => {
        return oldData.map(anecdote => 
          anecdote.id === updatedAnecdote.id ? updatedAnecdote : anecdote
        );
      });
    },
  });

  const result = useQuery({
    queryKey: ['anecdotes'],
    queryFn: getAnecdotes,
    retry: false,
  });

  if (result.isLoading) {
    return <div>loading data...</div>;
  }

  if (result.isError) {
    return <div>anecdote service not available due to problems in server</div>;
  }

  const anecdotes = result.data;

  const handleVote = (anecdote) => {
    updateAnecdoteMutation.mutate({ ...anecdote, votes: anecdote.votes + 1 });
  }

  return (
    <div>
      <h3>Anecdote app</h3>

      <Notification />
      <AnecdoteForm />

      {anecdotes.map(anecdote =>
        <div key={anecdote.id}>
          <div>
            {anecdote.content}
          </div>
          
          <div>
            has {anecdote.votes}
            <button onClick={() => handleVote(anecdote)}>vote</button>
          </div>
        </div>
      )}
    </div>
  );
}

export default App;

关键说明

  • 移除了原有的queryClient.invalidateQueries调用,彻底避免额外GET请求。
  • 利用oldData参数获取当前缓存数组,通过map精准替换对应ID的条目,确保缓存与服务器数据完全一致。
  • 依赖你的updateAnecdote接口返回更新后的完整数据(当前requests.js中的实现已满足此要求)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 23:06:16