如何为获取全部供应商的useQuery设置含supplier.id的queryKey?
解决React Query中供应商列表缓存的精准更新问题
首先要明确:获取全部供应商的查询,它的queryKey应该保持为['supplier']——这个键对应“所有供应商集合”的查询结果,不可能用单个供应商ID作为列表查询queryKey的一部分(因为列表接口返回的是多个资源,无法对应单个ID的查询标识)。你想要的“删除/更新时只影响对应供应商缓存”的需求,可以通过以下两种方案实现:
方案一:新增单个供应商查询,联动列表缓存
如果后端支持单个供应商的查询接口(比如GET /supplier/:id),可以拆分查询逻辑,实现缓存的精准失效:
- 定义单个供应商的查询钩子:
const useSupplier = (supplierId) => { return useQuery({ queryKey: ["supplier", supplierId], queryFn: async () => (await axios.get(`/supplier/${supplierId}`)).data, }); };
- 保持原有的全量供应商查询设置:
const { data: suppliers = [] } = useQuery({ queryKey: ["supplier"], queryFn: async () => (await axios.get("/supplier")).data, staleTime: 5 * 60 * 1000, // 根据业务需求设置缓存有效期 });
- 执行删除/更新操作时,精准失效单个缓存并手动更新列表:
const queryClient = useQueryClient(); // 更新供应商示例 const updateSupplier = async (supplierId, updatedData) => { await axios.put(`/supplier/${supplierId}`, updatedData); // 失效单个供应商的缓存,下次查询会重新拉取最新数据 queryClient.invalidateQueries({ queryKey: ["supplier", supplierId] }); // 手动更新列表缓存中的对应项,避免重新拉取全量数据 queryClient.setQueryData(["supplier"], (oldSuppliers) => { return oldSuppliers.map(supplier => supplier.id === supplierId ? {...supplier, ...updatedData} : supplier ); }); }; // 删除供应商示例 const deleteSupplier = async (supplierId) => { await axios.delete(`/supplier/${supplierId}`); queryClient.invalidateQueries({ queryKey: ["supplier", supplierId] }); // 从列表缓存中移除该供应商 queryClient.setQueryData(["supplier"], (oldSuppliers) => { return oldSuppliers.filter(supplier => supplier.id !== supplierId); }); };
方案二:不新增单个查询,直接修改列表缓存
如果后端没有单个供应商查询接口,只能通过全量接口获取数据,可在操作后直接修改['supplier']的缓存内容,避免失效整个列表查询:
const queryClient = useQueryClient(); // 更新操作 const handleUpdate = async (supplierId, updatedData) => { await axios.put(`/supplier/${supplierId}`, updatedData); queryClient.setQueryData(["supplier"], (oldSuppliers) => { if (!oldSuppliers) return []; return oldSuppliers.map(supplier => supplier.id === supplierId ? {...supplier, ...updatedData} : supplier ); }); }; // 删除操作 const handleDelete = async (supplierId) => { await axios.delete(`/supplier/${supplierId}`); queryClient.setQueryData(["supplier"], (oldSuppliers) => { if (!oldSuppliers) return []; return oldSuppliers.filter(supplier => supplier.id !== supplierId); }); };
这种方式无需重新拉取全量供应商数据,直接修改缓存中对应的项,性能更优,也能实现“精准更新”的效果。
内容的提问来源于stack exchange,提问作者CXY
相关产品推荐
相关产品推荐

