React-query:POST请求后实现数据重获取的更优方案
React组件层级

首页组件使用react-query获取数据,子组件UserForm执行POST请求提交数据。目前我通过props传递refetch方法,在POST请求完成后重新获取服务器数据,请问有没有更优的实现方式?
首页组件代码
export default function HomePage() { const { isLoading, isFetching, isError, refetch, data: users, } = useQuery(['users'], getUsers); if (isLoading) { return <h1>loading..!!!</h1>; } if (isError) { return <h1>error</h1>; } return ( <div> <UserForm refetch={refetch} /> <ul> {users.length ? ( users?.map((user: IUser) => <UserItem key={user.id} user={user} refetch={refetch}/>) ) : ( <li>data error</li> )} </ul> </div> ); }
UserForm组件提交函数
const handleSubmitAddUser = async (e: FormEvent<HTMLFormElement>) => { e.preventDefault(); if (name) { addUser(name) .then(() => { setName(''); refetch(); }) .catch((err) => console.error(err)); } };
更优实现方式:用react-query的useMutation结合缓存失效
不用手动传递refetch,借助react-query的缓存管理机制自动更新数据,具体实现如下:
1. 在UserForm中替换为useMutation
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useState } from 'react'; const UserForm = () => { const queryClient = useQueryClient(); const [name, setName] = useState(''); // 用useMutation包裹新增用户逻辑 const addUserMutation = useMutation({ mutationFn: (userName) => addUser(userName), onSuccess: () => { setName(''); // 标记'users'查询缓存失效,react-query会自动重新拉取数据 queryClient.invalidateQueries({ queryKey: ['users'] }); }, onError: (err) => console.error(err) }); const handleSubmitAddUser = (e: FormEvent<HTMLFormElement>) => { e.preventDefault(); if (name) { addUserMutation.mutate(name); } }; // 组件其余渲染逻辑... };
2. 首页组件移除refetch传递
export default function HomePage() { const { isLoading, isFetching, isError, data: users, } = useQuery(['users'], getUsers); if (isLoading) { return <h1>loading..!!!</h1>; } if (isError) { return <h1>error</h1>; } return ( <div> <UserForm /> {/* 无需传递refetch */} <ul> {users.length ? ( users?.map((user: IUser) => <UserItem key={user.id} user={user} />) {/* 也不用传refetch */} ) : ( <li>data error</li> )} </ul> </div> ); }
优势说明
- 组件解耦:子组件不再依赖父组件的refetch方法,降低耦合度
- 自动缓存管理:react-query接管缓存失效和重新请求逻辑,不用手动调用refetch
- 扩展性强:后续其他组件修改用户数据时,只需调用
invalidateQueries(['users'])就能统一更新数据
如果addUser接口会返回新增的用户数据,还可以直接更新缓存避免额外请求,效率更高:
onSuccess: (newUser) => { setName(''); // 直接更新缓存数据,跳过网络请求 queryClient.setQueryData(['users'], (oldUsers) => { return [...(oldUsers || []), newUser]; }); }
内容的提问来源于stack exchange,提问作者pvp11
相关产品推荐
相关产品推荐

