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

RTK Query同端点多mutation请求的isLoading状态单独校验方案

RTK Query多请求独立加载状态的常规处理方式

当你用单个RTK Query mutation发起多次不同请求,需要给每个请求(比如每个触发按钮)单独设置加载指示器时,常用这几种方式:

1. 手动维护请求状态映射表

用React的useState创建一个对象,以每个请求的唯一标识(比如数据ID、自定义请求key)为键,存储对应请求的加载状态。发起请求前标记为加载中,请求完成(无论成功失败)后取消标记:

import { useState } from 'react';
import { someApi } from './api';

function MyComponent() {
  const [makeRequest] = someApi.useMutation();
  const [requestLoading, setRequestLoading] = useState({});

  const handleRequest = async (data, requestKey) => {
    // 标记当前请求为加载中
    setRequestLoading(prev => ({ ...prev, [requestKey]: true }));
    try {
      await makeRequest(data).unwrap();
      // 请求成功后的逻辑
    } catch (err) {
      // 请求失败后的错误处理
    } finally {
      // 请求结束,取消加载状态
      setRequestLoading(prev => ({ ...prev, [requestKey]: false }));
    }
  };

  return (
    <>
      <button 
        onClick={() => handleRequest({ id: 1 }, 'req-1')} 
        disabled={requestLoading['req-1']}
      >
        {requestLoading['req-1'] ? '加载中...' : '发起请求1'}
      </button>
      <button 
        onClick={() => handleRequest({ id: 2 }, 'req-2')} 
        disabled={requestLoading['req-2']}
      >
        {requestLoading['req-2'] ? '加载中...' : '发起请求2'}
      </button>
    </>
  );
}

这种方式简单直接,完全自定义状态跟踪,适合场景简单的需求。

2. 利用RTK Query内置的请求跟踪功能

RTK Query允许开启mutation的请求跟踪,然后通过useMutationState钩子获取所有活跃请求的状态,需要给每个请求添加唯一标识来区分:

首先在定义mutation时开启跟踪:

// api定义文件
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const someApi = createApi({
  reducerPath: 'someApi',
  baseQuery: fetchBaseQuery({ baseUrl: '/' }),
  endpoints: (builder) => ({
    someMutation: builder.mutation({
      query: (data) => ({
        url: '/your-endpoint',
        method: 'POST',
        body: data,
      }),
      track: true, // 开启所有请求的状态跟踪
    }),
  }),
});

export const { useSomeMutationMutation } = someApi;

然后在组件中使用:

import { useSomeMutationMutation, someApi } from './api';

function MyComponent() {
  const [makeRequest] = useSomeMutationMutation();
  // 获取该mutation的所有请求状态
  const mutationStates = someApi.useMutationState({
    endpoint: 'someMutation',
  });

  // 发起请求时携带唯一的requestId作为meta标识
  const handleRequest = (data, requestId) => {
    makeRequest(data, { meta: { requestId } });
  };

  // 判断指定请求是否处于加载中
  const isRequestLoading = (requestId) => {
    return mutationStates.some(
      state => state.meta?.requestId === requestId && state.status === 'pending'
    );
  };

  return (
    <>
      <button 
        onClick={() => handleRequest({ id: 1 }, 'req-1')} 
        disabled={isRequestLoading('req-1')}
      >
        {isRequestLoading('req-1') ? '加载中...' : '发起请求1'}
      </button>
      <button 
        onClick={() => handleRequest({ id: 2 }, 'req-2')} 
        disabled={isRequestLoading('req-2')}
      >
        {isRequestLoading('req-2') ? '加载中...' : '发起请求2'}
      </button>
    </>
  );
}

这种方式复用RTK Query的内置状态管理,不需要手动维护状态对象,适合需要精细控制请求状态的场景。

3. 封装独立的请求按钮组件

把每个请求按钮和对应的mutation逻辑封装成独立组件,每个组件内部单独调用useMutation,这样每个组件天然拥有独立的isLoading状态:

import { someApi } from './api';

const RequestButton = ({ data, children }) => {
  const [makeRequest, { isLoading }] = someApi.useMutation();

  const handleClick = () => {
    makeRequest(data);
  };

  return (
    <button onClick={handleClick} disabled={isLoading}>
      {isLoading ? '加载中...' : children}
    </button>
  );
};

// 使用组件
function MyComponent() {
  return (
    <>
      <RequestButton data={{ id: 1 }}>发起请求1</RequestButton>
      <RequestButton data={{ id: 2 }}>发起请求2</RequestButton>
    </>
  );
}

这种方式代码解耦,状态完全隔离,适合需要复用请求按钮逻辑的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:01:18