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

React中如何将Axios拦截器响应/错误数据传递至其他组件

How to Pass Data from Axios Interceptors to React Components

Got it, let's break down how to share data from your Axios response/error interceptors with other React components. There are a few solid approaches depending on your app's size and complexity:

1. React Context API (Great for Small-to-Medium Apps)

Context is perfect if you don't want to add a full state management library. Here's how to set it up:

Step 1: Create a Context to Hold Interceptor Data

First, make a context to store the data and expose functions to update it:

// src/contexts/InterceptorContext.js
import { createContext, useContext, useState, useEffect } from 'react';

const InterceptorContext = createContext();

// Global variables to hold state updaters (since interceptors run outside React components)
let updateInterceptorData = null;
let updateGenericError = null;

export function InterceptorProvider({ children }) {
  const [interceptorData, setInterceptorData] = useState(null);
  const [genericError, setGenericError] = useState(null);

  useEffect(() => {
    // Assign updaters to global variables when Provider mounts
    updateInterceptorData = setInterceptorData;
    updateGenericError = setGenericError;

    // Clean up when Provider unmounts
    return () => {
      updateInterceptorData = null;
      updateGenericError = null;
    };
  }, []);

  return (
    <InterceptorContext.Provider value={{ interceptorData, genericError }}>
      {children}
    </InterceptorContext.Provider>
  );
}

// Custom hook to access the context
export function useInterceptorData() {
  return useContext(InterceptorContext);
}

// Export updaters for interceptors to use
export { updateInterceptorData, updateGenericError };

Step 2: Wrap Your App with the Provider

Add the provider to your root component so all components can access the context:

// src/App.js
import { InterceptorProvider } from './contexts/InterceptorContext';
import YourTargetComponent from './components/YourTargetComponent';

function App() {
  return (
    <InterceptorProvider>
      <YourTargetComponent />
    </InterceptorProvider>
  );
}

export default App;

Step 3: Update Axios Interceptors to Use the Context Updaters

Modify your Axios instance to call the context updaters when the conditions are met:

// src/utils/axios.js
import axios from 'axios';
import { updateInterceptorData, updateGenericError } from '../contexts/InterceptorContext';

const api = axios.create();

api.interceptors.response.use(
  function (response) {
    if (response.headers.TestFlag === 'True') {
      // Pass the relevant data (adjust response.data to whatever you need)
      if (updateInterceptorData) {
        updateInterceptorData(response.data);
      }
    }
    return response;
  },
  function (error) {
    if (error.response?.data?.title === 'Generic error') {
      // Pass the error details
      if (updateGenericError) {
        updateGenericError(error.response.data);
      }
    }
    // Important: Reject the error so calling code can handle it too
    return Promise.reject(error);
  }
);

export default api;

Step 4: Access the Data in Your Component

Use the custom hook to retrieve the data in any component:

// src/components/YourTargetComponent.js
import { useInterceptorData } from '../contexts/InterceptorContext';

function YourTargetComponent() {
  const { interceptorData, genericError } = useInterceptorData();

  return (
    <div>
      {interceptorData && (
        <div>
          <h3>Data from Interceptor:</h3>
          <pre>{JSON.stringify(interceptorData, null, 2)}</pre>
        </div>
      )}
      {genericError && (
        <div className="error-message">
          <h3>Error:</h3>
          <p>{genericError.message}</p>
        </div>
      )}
    </div>
  );
}

export default YourTargetComponent;

2. Redux Toolkit (Best for Large/Complex Apps)

If your app already uses Redux or has complex state flows, this is the way to go:

Step 1: Create a Slice for Interceptor State

// src/slices/interceptorSlice.js
import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  interceptorData: null,
  genericError: null,
};

const interceptorSlice = createSlice({
  name: 'interceptor',
  initialState,
  reducers: {
    setInterceptorData: (state, action) => {
      state.interceptorData = action.payload;
    },
    setGenericError: (state, action) => {
      state.genericError = action.payload;
    },
    clearInterceptorState: (state) => {
      state.interceptorData = null;
      state.genericError = null;
    },
  },
});

export const { setInterceptorData, setGenericError, clearInterceptorState } = interceptorSlice.actions;
export default interceptorSlice.reducer;

Step 2: Configure the Redux Store

// src/store.js
import { configureStore } from '@reduxjs/toolkit';
import interceptorReducer from './slices/interceptorSlice';

export const store = configureStore({
  reducer: {
    interceptor: interceptorReducer,
  },
});

Step 3: Wrap Your App with the Redux Provider

// src/App.js
import { Provider } from 'react-redux';
import { store } from './store';
import YourTargetComponent from './components/YourTargetComponent';

function App() {
  return (
    <Provider store={store}>
      <YourTargetComponent />
    </Provider>
  );
}

export default App;

Step 4: Update Axios Interceptors to Dispatch Redux Actions

// src/utils/axios.js
import axios from 'axios';
import { store } from '../store';
import { setInterceptorData, setGenericError } from '../slices/interceptorSlice';

const api = axios.create();

api.interceptors.response.use(
  function (response) {
    if (response.headers.TestFlag === 'True') {
      store.dispatch(setInterceptorData(response.data));
    }
    return response;
  },
  function (error) {
    if (error.response?.data?.title === 'Generic error') {
      store.dispatch(setGenericError(error.response.data));
    }
    return Promise.reject(error);
  }
);

export default api;

Step 5: Access the State in Your Component

// src/components/YourTargetComponent.js
import { useSelector, useDispatch } from 'react-redux';
import { clearInterceptorState } from '../slices/interceptorSlice';

function YourTargetComponent() {
  const { interceptorData, genericError } = useSelector(state => state.interceptor);
  const dispatch = useDispatch();

  return (
    <div>
      {interceptorData && (
        <div>
          <h3>Interceptor Data:</h3>
          <pre>{JSON.stringify(interceptorData, null, 2)}</pre>
          <button onClick={() => dispatch(clearInterceptorState())}>Clear Data</button>
        </div>
      )}
      {genericError && (
        <div className="error">
          <h3>Generic Error:</h3>
          <p>{genericError.message}</p>
          <button onClick={() => dispatch(clearInterceptorState())}>Clear Error</button>
        </div>
      )}
    </div>
  );
}

export default YourTargetComponent;

3. Custom Browser Events (Quick & Simple for Isolated Cases)

If you just need a lightweight solution without state management, use custom events:

Step 1: Trigger Events in Axios Interceptors

// src/utils/axios.js
import axios from 'axios';

const api = axios.create();

api.interceptors.response.use(
  function (response) {
    if (response.headers.TestFlag === 'True') {
      // Create and dispatch a custom event with your data
      const dataEvent = new CustomEvent('interceptor-data-received', {
        detail: response.data
      });
      window.dispatchEvent(dataEvent);
    }
    return response;
  },
  function (error) {
    if (error.response?.data?.title === 'Generic error') {
      const errorEvent = new CustomEvent('generic-error-occurred', {
        detail: error.response.data
      });
      window.dispatchEvent(errorEvent);
    }
    return Promise.reject(error);
  }
);

export default api;

Step 2: Listen for Events in Your Component

// src/components/YourTargetComponent.js
import { useState, useEffect } from 'react';

function YourTargetComponent() {
  const [interceptorData, setInterceptorData] = useState(null);
  const [genericError, setGenericError] = useState(null);

  useEffect(() => {
    // Handler for data events
    function handleDataReceived(e) {
      setInterceptorData(e.detail);
    }

    // Handler for error events
    function handleErrorOccurred(e) {
      setGenericError(e.detail);
    }

    // Add event listeners
    window.addEventListener('interceptor-data-received', handleDataReceived);
    window.addEventListener('generic-error-occurred', handleErrorOccurred);

    // Clean up listeners when component unmounts
    return () => {
      window.removeEventListener('interceptor-data-received', handleDataReceived);
      window.removeEventListener('generic-error-occurred', handleErrorOccurred);
    };
  }, []);

  return (
    <div>
      {interceptorData && <div>Data: {JSON.stringify(interceptorData)}</div>}
      {genericError && <div className="error">Error: {genericError.message}</div>}
    </div>
  );
}

export default YourTargetComponent;

Quick Notes:

  • Always make sure to clean up event listeners or context references to avoid memory leaks.
  • In the interceptor, don't forget to return Promise.reject(error) instead of console.error—this lets components using the Axios call handle the error too if needed.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 18:27:53