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

如何在React Context中更新API错误及处理useEffect依赖

全局API错误处理方案(React Context + Axios拦截器)

一、核心问题分析

你最初的代码失效是因为React Hook(如useContext)只能在React组件或自定义Hook内部调用,而Axios拦截器的初始化代码不在组件生命周期内,所以无法直接使用useContext更新上下文状态。

二、完整实现步骤

1. 正确配置错误上下文(Context)

首先需要用useState管理错误状态,确保上下文提供可更新的状态和方法:

import { createContext, useState, useContext } from 'react';

// 创建错误上下文
const APIErrorContext = createContext({
  error: '',
  setError: () => {},
});

// 自定义Hook简化上下文调用
export const useAPIError = () => useContext(APIErrorContext);

// 上下文提供者组件
export const APIErrorProvider = ({ children }) => {
  const [error, setError] = useState('');

  return (
    <APIErrorContext.Provider value={{ error, setError }}>
      {children}
    </APIErrorContext.Provider>
  );
};

2. 实现Axios错误拦截器组件

将拦截器的初始化逻辑放到React组件内部的useEffect中,这样就能合法调用useContext:

import { useEffect } from 'react';
import axios from 'axios';
import { useAPIError } from './APIErrorContext';

const AxiosErrorHandler = ({ children }) => {
  const { setError } = useAPIError();

  useEffect(() => {
    // 注册响应拦截器
    const responseInterceptor = axios.interceptors.response.use(
      (response) => response, // 正常响应直接返回
      (error) => {
        // 安全提取错误信息(兼容无响应的网络错误)
        const errorMsg = error.response?.data?.message || error.message || '未知错误';
        setError(errorMsg);
        
        // 继续抛出错误,允许单个请求自行处理
        return Promise.reject(error);
      }
    );

    // 组件卸载时移除拦截器,避免内存泄漏
    return () => {
      axios.interceptors.response.eject(responseInterceptor);
    };
  }, [setError]); // 依赖项传入setError,遵循React Hook规则(setError来自useState,稳定不会频繁变化)

  return children;
};

export default AxiosErrorHandler;

3. 整合到App组件中

在根组件中嵌套上下文提供者和错误拦截器组件:

import { APIErrorProvider } from './APIErrorContext';
import AxiosErrorHandler from './AxiosErrorHandler';
import ChildComponent from './ChildComponent';
import ErrorModal from './ErrorModal';

const App = () => {
  return (
    <APIErrorProvider>
      <AxiosErrorHandler>
        <ChildComponent />
        <ErrorModal /> {/* 全局错误弹窗组件 */}
      </AxiosErrorHandler>
    </APIErrorProvider>
  );
};

export default App;

4. 实现全局错误弹窗组件

订阅上下文状态,自动展示错误信息:

import { useAPIError } from './APIErrorContext';

const ErrorModal = () => {
  const { error, setError } = useAPIError();

  if (!error) return null;

  return (
    <div style={{ position: 'fixed', top: 0, left: 0, right: 0, padding: '1rem', background: '#ff4444', color: 'white' }}>
      <p>{error}</p>
      <button onClick={() => setError('')} style={{ marginLeft: '1rem' }}>关闭</button>
    </div>
  );
};

export default ErrorModal;

三、关于useEffect依赖项的说明

useEffect的依赖数组需要传入setError,原因如下:

  • 虽然useState返回的setError是稳定函数(不会随组件渲染变化),但遵循React Hook规则,必须将所有在effect内部使用的外部变量加入依赖数组
  • 这样可以避免ESLint警告,同时保证逻辑的严谨性

内容的提问来源于stack exchange,提问作者kishore.jannarapu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 07:54:56