如何在react-query中实现点击按钮后才执行useQueries?
批量删除文章的React Query Hook修复方案
问题分析
你当前的实现存在两个核心问题:
- 状态重置时机错误:组件中
enabled && setEnabled(false)会在enabled变为true的下一次渲染立刻将其重置为false,React Query的useQueries还没来得及触发API请求就被禁用了。 - API操作类型不匹配:
useQueries设计用于并行执行查询类操作(获取数据),而删除属于写操作,更适合用React Query的useMutation来处理,它专门针对创建、更新、删除这类修改数据的场景。
方案一:使用useMutation实现批量删除(推荐)
这是React Query处理写操作的标准方式,逻辑更清晰,也更符合框架设计意图:
自定义Hook实现
import { useMutation } from '@tanstack/react-query'; export const useDeleteArticles = ({ onSuccess }) => { return useMutation({ // 并行执行所有删除请求 mutationFn: (ids) => Promise.all(ids.map(id => articlesApi.destroy(id))), // 所有请求完成后触发成功回调 onSuccess: () => { onSuccess?.(); }, // 可选:统一处理错误 onError: (error) => { console.error('删除失败:', error); } }); };
组件中使用
const deleteMutation = useDeleteArticles({ onSuccess: refetch }); const handleArticleDelete = () => { // 直接传入要删除的ID数组,触发批量删除 deleteMutation.mutate(ids); };
这种方式无需手动管理enabled状态,mutate方法会在你调用时直接触发请求,请求完成后自动调用onSuccess。
方案二:修复原有useQueries的实现
如果你坚持使用useQueries,需要调整状态重置的时机,确保请求有足够时间触发:
修改自定义Hook
export const useDeleteArticles = ({ ids, onSuccess, enabled }) => { const queryResult = useQueries({ queries: ids.map(id => ({ queryKey: ["article-delete", id], queryFn: () => articlesApi.destroy(id), enabled })) }); const isLoading = queryResult.some(result => result.isLoading); const allSettled = queryResult.every(result => result.isSuccess || result.isError); // 所有请求完成后触发回调 if (allSettled && !isLoading) { onSuccess?.(); } return { isLoading, queryResult }; };
修改组件中的状态管理
const [enabled, setEnabled] = useState(false); const { isLoading } = useDeleteArticles({ ids, onSuccess: () => { refetch(); // 请求完成后再重置enabled setEnabled(false); }, enabled }); const handleArticleDelete = () => { setEnabled(true); };
这里去掉了原有的enabled && setEnabled(false),改为在onSuccess回调中重置enabled,确保所有删除请求完成后才禁用,避免提前终止请求。
内容的提问来源于stack exchange,提问作者Anmol Shrivastav
相关产品推荐
相关产品推荐

