What is Axios Interceptors in React
This article explains what Axios interceptors are and how to use them in a React application. You will learn how interceptors act as middleware for your HTTP requests and responses, allowing you to globally manage authentication tokens, handle API errors, and log data without duplicating code across your components.
Understanding Axios Interceptors
Axios interceptors are functions that Axios calls automatically
before a request is sent to the server, or before a response is passed
to the .then() or .catch() blocks in your
application code.
Think of them as a toll booth or middleware for your network requests. Instead of manually adding authorization headers or error-handling logic to every single API call in your React components, you can define these rules once globally.
There are two main types of interceptors: 1. Request Interceptors: Triggered right before an HTTP request leaves your application. 2. Response Interceptors: Triggered as soon as a response arrives from the server, but before your application code processes it.
Common Use Cases in React
- Attaching Auth Tokens: Automatically injecting a
JWT (JSON Web Token) from local storage or state into the
Authorizationheader of every outgoing request. - Global Error Handling: Catching specific HTTP
status codes (like
401 Unauthorizedor500 Internal Server Error) to redirect users to a login page or display a global notification. - Loading States: Triggering global loading spinners when a request starts and stopping them when the response arrives.
- Data Formatting: Standardizing or transforming response data before it reaches your React components.
How to Implement Interceptors in React
To implement interceptors cleanly, it is best practice to create a dedicated Axios instance. This prevents pollution of the global Axios object and allows you to configure different behavior for different APIs.
Here is a practical example of setting up a request and response interceptor:
import axios from 'axios';
// 1. Create an Axios instance
const apiClient = axios.create({
baseURL: 'https://api.example.com',
headers: {
'Content-Type': 'application/json',
},
});
// 2. Add a Request Interceptor
apiClient.interceptors.request.use(
(config) => {
// Retrieve the token (e.g., from localStorage)
const token = localStorage.getItem('userToken');
// If the token exists, inject it into the headers
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
// Handle request errors
return Promise.reject(error);
}
);
// 3. Add a Response Interceptor
apiClient.interceptors.response.use(
(response) => {
// Any status code within the range of 2xx triggers this function
return response;
},
(error) => {
// Any status codes outside the range of 2xx trigger this function
if (error.response && error.response.status === 401) {
// Handle unauthorized errors (e.g., redirect to login, clear storage)
console.warn('Unauthorized! Redirecting to login...');
localStorage.removeItem('userToken');
window.location.href = '/login';
}
return Promise.reject(error);
}
);
export default apiClient;Managing Interceptors in React Lifecycles
In some advanced React applications, you may want to attach interceptors inside a React hook or component to access state (like a Redux store or React Context).
If you register interceptors inside a component or custom hook, you must eject (remove) them when the component unmounts to prevent memory leaks and duplicate interceptor executions.
import { useEffect } from 'react';
import apiClient from './apiClient';
function App() {
useEffect(() => {
const myInterceptor = apiClient.interceptors.request.use(config => {
// Modify config
return config;
});
// Clean up the interceptor when the component unmounts
return () => {
apiClient.interceptors.request.eject(myInterceptor);
};
}, []);
return <div>My React App</div>;
}Using Axios interceptors keeps your React components clean, dry (Don’t Repeat Yourself), and focused solely on rendering UI rather than managing low-level API configurations.