React Query多批量删除Mutation时仅执行一次查询失效的实现
解决方案
核心思路
- 给删除角色的mutation添加mutationKey,用于追踪批量操作中的所有mutation实例
- 用状态记录是否有至少一次删除成功
- 监听所有mutation的运行状态,当全部完成且存在成功案例时,仅执行一次查询失效操作
代码实现
import { axios, getEndpoint } from "@/api" import { ResponseData } from "@/api/types" import { useMutation, useQueryClient, useIsMutating } from "@tanstack/react-query" import { rolesKey } from "./useRolesQuery" import { useState, useEffect } from "react" export const deleteRoleFn = (id: number | string) => { return axios.delete<ResponseData<[]>>(getEndpoint("role", { id })) } export const useDeleteRole = () => { const queryClient = useQueryClient() // 标记是否有至少一次删除成功 const [hasSuccessfulDelete, setHasSuccessfulDelete] = useState(false) // 监听所有deleteRole类型的mutation运行状态 const isMutating = useIsMutating({ mutationKey: ['deleteRole'] }) const mutation = useMutation({ // 添加mutationKey,用于批量追踪 mutationKey: ['deleteRole'], mutationFn: deleteRoleFn, onSuccess: (_, id) => { // 只要有一次成功,就标记为true setHasSuccessfulDelete(true) // 移除单个角色的缓存查询 queryClient.removeQueries({ queryKey: getRoleKey(id) }) } }) useEffect(() => { // 当所有mutation都执行完成,且存在成功删除时 if (isMutating === 0 && hasSuccessfulDelete) { // 仅执行一次角色列表查询失效 queryClient.invalidateQueries({ queryKey: rolesKey }) // 重置状态,避免影响下一次批量操作 setHasSuccessfulDelete(false) } }, [isMutating, hasSuccessfulDelete, queryClient, rolesKey]) return mutation }
方案说明
- mutationKey的作用:通过
['deleteRole']标识所有删除角色的mutation实例,useIsMutating可以精准获取当前是否有该类型的mutation在运行 - 状态追踪:
hasSuccessfulDelete确保只要有一次删除成功,就会触发后续的列表查询失效 - 批量完成后的触发逻辑:
useEffect监听isMutating从非0变为0(即所有批量操作完成),同时结合成功标记,仅执行一次invalidateQueries,避免重复调用 - 原逻辑保留:单个角色删除成功后,依然会移除对应角色的缓存查询,不影响原有单删的缓存优化
内容的提问来源于stack exchange,提问作者Ardalan
相关产品推荐
相关产品推荐

