如何在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
相关产品推荐
相关产品推荐

