React-Query:useMutation/useQuery与isLoading,如何保持按钮禁用至新数据返回
解决React Query中mutation后按钮需保持禁用直至新数据返回的问题
你的问题核心在于:mutation完成后isMutating变为false,但此时query正在后台重新获取数据,导致按钮提前启用,而新数据尚未加载完成。要解决这个问题,需要把mutation的加载状态和query的后台刷新状态结合起来作为按钮禁用的判断条件。
具体修改步骤:
- 从
useQuery的返回值中解构出isFetching状态(该状态会在query后台重新获取数据时变为true,区别于仅初始加载时生效的isLoading) - 将按钮的
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
相关产品推荐
相关产品推荐

