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

React Query 如何通过同一个useMutation实现并行请求独立加载状态

你当前的写法无法实现需求,核心原因是单个useMutation实例仅能跟踪一次 mutation 请求的状态,每次触发新的 mutation 会覆盖旧的状态,自然无法并行跟踪多个不同请求的加载状态。这里提供两种常用的落地方案:

方案一:抽离子组件独立维护 mutation(推荐)

将循环渲染的每一行用户项抽为单独的子组件,每个子组件内部持有独立的useMutation实例,状态天然隔离,完全支持并行请求互不影响,是最简单通用的方案。

// 抽离独立的用户行组件,每个组件维护自己的mutation状态
const UserItem = ({ entry }) => {
  const userMutation = useMutation({
    mutationFn: async (userData) => {
      return await axios.post("https://reqres.in/api/users", userData);
    }
  });

  const handleClick = () => {
    userMutation.mutate(entry);
  };

  return (
    <div>
      {entry.userName}
      <button onClick={handleClick} disabled={userMutation.isLoading}>
        post stuff
      </button>
      {userMutation.isLoading && <span>SPINNER</span>}
    </div>
  )
}

// 父组件只需循环渲染子组件即可
const Parent = () => {
  return (
    <>
      <span>parallel mutations:</span>
      {data.map((entry) => <UserItem key={entry.userName} entry={entry} />)}
    </>
  )
}
方案二:使用useMutationState全局筛选状态

如果你需要在父组件统一管理所有 mutation 状态,可以用 react-query 内置的useMutationStateAPI,通过给每个请求打唯一的mutationKey标记,再按 key 筛选对应请求的状态即可。

// 定义公共mutation hook
const useUserMutation = () => {
  return useMutation({
    mutationFn: async (userData) => {
      return await axios.post("https://reqres.in/api/users", userData);
    }
  })
}

const Parent = () => {
  const userMutation = useUserMutation();

  const handleClick = (userData) => {
    // 触发请求时传入唯一mutationKey做标记
    userMutation.mutate(userData, {
      mutationKey: ['userMutation', userData.userName]
    })
  }

  return (
    <>
      <span>parallel mutations:</span>
      {data.map((entry) => {
        // 按mutationKey筛选当前用户对应的请求状态
        const [isLoading] = useMutationState({
          filters: { mutationKey: ['userMutation', entry.userName], status: 'pending' },
          select: (mutation) => mutation.state.isLoading
        })
        return (
          <div key={entry.userName}>
            {entry.userName}
            <button onClick={() => handleClick(entry)} disabled={isLoading}>
              post stuff
            </button>
            {isLoading && <span>SPINNER</span>}
          </div>
        )
      })}
    </>
  )
}

两种方案按需选择即可:子组件方案逻辑简单无额外学习成本,适合绝大多数业务场景;useMutationState方案适合需要在父层聚合统计所有 mutation 状态的特殊场景。

内容的提问来源于stack exchange,提问作者Ognjen Mišić

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 18:54:03