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

能否用Redux RTK实现拦截器处理错误?还有哪些替代方案?

RTK Query的拦截器替代方案及错误处理方法

RTK Query没有和Axios完全一致的“拦截器”概念,但可以通过以下几种机制实现类似的请求/响应拦截、全局或局部错误处理:

1. 基于Axios自定义baseQuery(直接复用Axios拦截器)

如果习惯Axios的拦截器逻辑,可以把Axios作为RTK Query的底层请求工具,自定义baseQuery后直接配置Axios的请求/响应拦截器。

示例代码:

import axios from 'axios';
import { createApi } from '@reduxjs/toolkit/query/react';

// 配置Axios实例和拦截器
const axiosInstance = axios.create({ baseURL: 'https://api.example.com' });

// 请求拦截器:统一添加请求头
axiosInstance.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => Promise.reject(error)
);

// 响应拦截器:统一处理错误状态码
axiosInstance.interceptors.response.use(
  (response) => response,
  (error) => {
    if (error.response?.status === 401) {
      // 处理未授权逻辑,比如清除token、跳转登录页
      localStorage.removeItem('token');
      window.location.href = '/login';
    }
    return Promise.reject(error);
  }
);

// 自定义Axios版baseQuery
const axiosBaseQuery =
  ({ baseUrl } = { baseUrl: '' }) =>
  async ({ url, method, data, params }) => {
    try {
      const result = await axiosInstance({ url: baseUrl + url, method, data, params });
      return { data: result.data };
    } catch (axiosError) {
      return {
        error: {
          status: axiosError.response?.status,
          data: axiosError.response?.data || axiosError.message,
        },
      };
    }
  };

// 创建API时使用自定义baseQuery
export const api = createApi({
  reducerPath: 'api',
  baseQuery: axiosBaseQuery({ baseUrl: 'https://api.example.com' }),
  endpoints: (builder) => ({
    getPosts: builder.query({
      query: () => '/posts',
    }),
  }),
});

2. 使用RTK Query内置的transformRequest/transformResponse

这两个配置可以在单个endpoint级别,对请求数据(发送前)和响应数据(成功返回后)做转换处理,相当于轻量的请求/响应拦截:

export const api = createApi({
  reducerPath: 'api',
  baseQuery: fetchBaseQuery({ baseUrl: 'https://api.example.com' }),
  endpoints: (builder) => ({
    createPost: builder.mutation({
      query: (postData) => ({
        url: '/posts',
        method: 'POST',
        body: postData,
      }),
      // 请求发送前格式化数据
      transformRequest: (postData) => {
        return { ...postData, createdAt: new Date().toISOString() };
      },
      // 成功响应后处理返回结果
      transformResponse: (responseData) => {
        return { id: responseData.id, title: responseData.title.toUpperCase() };
      },
    }),
  }),
});

3. 全局/局部错误处理

全局错误处理

在createApi时包装baseQuery,实现所有请求的错误统一处理:

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

const baseQuery = fetchBaseQuery({ baseUrl: 'https://api.example.com' });

const baseQueryWithErrorHandling = async (args, api, extraOptions) => {
  const result = await baseQuery(args, api, extraOptions);
  if (result.error) {
    // 全局错误处理逻辑:比如上报错误、弹出提示
    console.error('全局捕获错误:', result.error);
    if (result.error.status === 403) {
      api.dispatch(logout());
    }
  }
  return result;
};

export const api = createApi({
  reducerPath: 'api',
  baseQuery: baseQueryWithErrorHandling,
  endpoints: (builder) => ({ /* ... */ }),
});

单个请求的错误处理

调用查询/突变钩子时,通过onError回调处理单个请求的专属错误:

const { mutate } = useCreatePostMutation();

const handleCreatePost = (postData) => {
  mutate(postData, {
    onError: (error) => {
      alert(`创建帖子失败: ${error.data.message}`);
    },
    onSuccess: (data) => {
      // 成功回调逻辑
    },
  });
};

4. 自动重试机制

RTK Query内置重试功能,可在全局或单个endpoint级别配置,自动重试失败的请求:

// 全局配置重试规则
export const api = createApi({
  reducerPath: 'api',
  baseQuery: fetchBaseQuery({ baseUrl: 'https://api.example.com' }),
  retry: 3, // 最多重试3次
  retryDelay: (retryCount) => retryCount * 1000, // 每次重试间隔递增1秒
  endpoints: (builder) => ({ /* ... */ }),
});

// 单个endpoint覆盖全局配置
getPosts: builder.query({
  query: () => '/posts',
  retry: 1, // 仅重试1次
}),

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:23:13