You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-Query:useMutation/useQuery与isLoading,如何保持按钮禁用至新数据返回

解决React Query中mutation后按钮需保持禁用直至新数据返回的问题

你的问题核心在于:mutation完成后isMutating变为false,但此时query正在后台重新获取数据,导致按钮提前启用,而新数据尚未加载完成。要解决这个问题,需要把mutation的加载状态和query的后台刷新状态结合起来作为按钮禁用的判断条件。

具体修改步骤:

  1. 从useQuery的返回值中解构出isFetching状态(该状态会在query后台重新获取数据时变为true,区别于仅初始加载时生效的isLoading)
  2. 将按钮的disabled属性改为isMutating || isFetching,确保只要mutation未完成,或者query正在刷新数据,按钮就保持禁用

修改后的完整代码如下:

const queryClient = useQueryClient();
const {
  isLoading,
  error,
  data: todos,
  isFetching, // 新增:获取query后台刷新状态
} = useQuery<Todo[]>("todos", fetchTodos);
const { mutate, isLoading: isMutating } = useMutation(addTodo, {
  onSuccess: () => {
    queryClient.invalidateQueries("todos");
  },
});

const handleAddTodo = () => {
  if (!todos) return;
  mutate({ id: todos.length + 1, title: "New Todo", completed: false });
};

if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error fetching todos.</div>;
if (!todos) return <div>Unexpected missing data</div>;

return (
  <>
    <button disabled={isMutating || isFetching} onClick={handleAddTodo}>
      {/* 可选:添加加载状态文本 */}
      {isMutating || isFetching ? "Adding..." : "Add Todo"}
    </button>
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>
          {todo.completed ? "☑" : "☐"} - {todo.title}
        </li>
      ))}
    </ul>
  </>
);

流程说明:

  • 点击按钮:isMutating变为true,按钮禁用
  • mutation请求完成:isMutating变为false,但invalidateQueries触发query重新获取数据,此时isFetching变为true,按钮保持禁用
  • query请求完成:isFetching变为false,按钮启用,同时新数据渲染完成

这样就能保证按钮在整个数据更新流程(mutation + query刷新)结束前一直处于禁用状态,符合你的需求。

内容的提问来源于stack exchange,提问作者Vanuan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:43:02