Data Fetching
Axios
Master Axios in React, covering client instances, automatic JSON parsing, request/response interceptors, and error handling.
1. Learning Objectives
In this lesson, you will learn how to integrate Axios for robust API communication. By the end of this topic, you will be able to:
- Configure custom API client instances using
axios.create. - Explain the benefits of automatic JSON transformation in Axios.
- Implement Request and Response Interceptors to manage auth tokens globally.
- Handle network and HTTP errors reliably using
axios.isAxiosError. - Cancel pending requests using standard abort signals in Axios.
2. Overview
**Axios** is a popular promise-based HTTP client for the browser and Node.js. It simplifies data fetching in React applications by providing features like automatic JSON parsing, request/response interceptors, and robust error handling out of the box, making it a powerful alternative to the native Fetch API.
3. Why This Topic Matters
Axios is the industry standard for managing API request pipelines in production:
- Request/Response Interceptors: You can intercept requests or responses before they are handled by
thenorcatch. This is useful for automatically attaching authorization headers to outgoing requests, or intercepting `401 Unauthorized` responses to refresh tokens or log out users globally. - Automatic JSON Translation: Axios automatically parses JSON responses and serializes request bodies, eliminating the need for manual `res.json()` calls.
- Unified Error Handling: Unlike `fetch`, Axios rejects the promise automatically on non-2xx HTTP status codes (like 404 or 500), making error handling more consistent.
4. Real-World Analogy
Think of Axios like **an executive shipping service**:
- Fetch API (Self-Service Mail): You must package the box yourself (serialize JSON), fill out custom custom forms manually, inspect the tracking status to see if it was delivered correctly (checking `res.ok`), and throw errors manually if the package is returned damaged.
- Axios (Executive Courier): The courier packages the item for you (automatic JSON serialization), runs check-stops along the route to attach tracking tags (interceptors), and automatically flags the delivery as failed if the recipient declines the package (automatically rejecting on 4xx/5xx errors). It is a premium, fully-managed service.
5. Core Concepts
Below is a comparison of the native Fetch API and Axios:
| Feature | Fetch API | Axios HTTP Client |
|---|---|---|
| JSON Handling | Manual stringification for bodies and manual res.json() parsing. |
Automatic JSON serialization and parsing. |
| HTTP Error Statuses | Resolves promise normally. Must check res.ok manually. |
Automatically rejects promise on non-2xx status codes. |
| Interceptors | No native support. Must wrap fetch calls manually. | Supported natively for both requests and responses. |
| Request Cancellation | Supported via AbortController. |
Supported via AbortController (or legacy CancelToken). |
6. Syntax & API Reference
This example shows how to configure an Axios client instance with interceptors:
7. Visual Diagram
This diagram displays how requests and responses flow through Axios interceptors:
8. Live Example — Full Working Code
Below is a complete, single-file HTML page demonstrating Axios instance creation, interceptors, and error handling:
What just happened? The application requests data using our custom `apiClient` instance. Opening the browser console shows that the request interceptor automatically attaches a custom header (X-Custom-Client-Header) to the outgoing request, and the response interceptor logs updates before passing control back to the component.
9. Interactive Playground
Try It Yourself Challenges:
- Change the base URL in
axios.createto an invalid address to trigger an error, and verify how the response interceptor catches it. - Create a post request using
apiClient.post, passing a payload object, and verify that the data is automatically serialized.
10. Common Mistakes
| Mistake | Why it happens | Wrong | Correct |
|---|---|---|---|
| Forgetting to return config inside request interceptors | Request interceptors must return the modified config object. Forgetting to return it halts the request, preventing it from ever being sent. |
axios.interceptors.request.use((config) => { (no return) |
axios.interceptors.request.use((config) => { |
| Manually parsing JSON response bodies | Axios handles JSON parsing and serialization automatically. Calling `JSON.parse` or `JSON.stringify` manually is redundant and can lead to errors. | apiClient.post('/user', JSON.stringify(data)) |
apiClient.post('/user', data) (let Axios serialize the object) |
11. Best Practices
- Use Client Instances: Always use `axios.create()` to create configured API client instances instead of calling the global `axios` object directly.
- Leverage Interceptors: Use interceptors to handle authentication tokens, API base paths, and global errors centrally.
- Handle Errors Safely: Use `axios.isAxiosError(error)` to identify Axios-specific errors and inspect their HTTP status codes safely.
- Clean up requests: Pass abort signals (`signal`) to Axios requests to allow canceling them on component unmounts.
12. Browser Compatibility/Requirements
Axios is supported in all modern browsers.
13. Interview Questions
Q1: How do Axios interceptors work? Give a practical use case in a React application.
Answer: Interceptors allow you to intercept requests or responses before they are handled by `then` or `catch` blocks. A common use case is adding authorization headers: a request interceptor can fetch the user's auth token from storage and attach it to the `Authorization` header of all outgoing requests automatically, keeping individual components free of auth boilerplate.
Q2: How does error handling differ between Axios and the native Fetch API?
Answer:
- Fetch API: Only rejects the promise on network failures. Non-2xx HTTP responses (like 404 or 500) resolve normally, requiring manual checks on `res.ok`.
- Axios: Automatically rejects the promise for any response with a status code outside the 2xx range, sending the request error directly to the `catch` block for consistent error handling.
14. Debugging Exercise
Identify why this global response interceptor blocks all API calls, causing the application to hang on updates:
Diagnosis: The interceptor's error handler catches the rejection but does not return a rejected promise. This resolves the promise chain as `undefined`, hiding the error from the calling component's `.catch()` block and causing the application to hang.
Fix: Return Promise.reject(error) at the end of the error handler to forward the error correctly:
15. Practice Exercises
Exercise 1: Create an API client instance with error handling
Build an Axios client instance named todoClient. Set a timeout threshold of 3 seconds. Configure a response interceptor to intercept `500 Server Error` responses, logging a "Server under maintenance" alert.
16. Scenario-Based Challenge
The Silent Token Refresh Interceptor:
You are designing a secure dashboard. If an API request fails with a `401 Unauthorized` status (due to an expired access token), the application should call a refresh token endpoint to get a new token, update local storage, and retry the original request silently. Describe how you would implement this using Axios response interceptors.
17. Quick Quiz
Q1: Which method is used to determine if a caught error object is an Axios-specific error?
A) error.isAxios
B) axios.isAxiosError(error)
C) error instanceof AxiosError
Answer: B — axios.isAxiosError(error) is the standard method used to identify and handle Axios-specific errors.
18. Summary & Key Takeaways
- Axios is a promise-based HTTP client that simplifies API communication.
- Use
axios.createto configure reusable API client instances. - Use request and response interceptors to handle tokens and errors centrally.
- Axios automatically parses JSON responses and serializes request bodies.
- Use
axios.isAxiosErrorto identify and handle API errors safely.
19. Cheat Sheet
| Axios API Element | Description |
|---|---|
axios.create({ baseURL, timeout }) |
Creates a configured Axios client instance. |
client.interceptors.request.use(fn) |
Intercepts and modifies outgoing API requests. |
client.interceptors.response.use(fn) |
Intercepts and processes incoming responses globally. |
axios.isAxiosError(err) |
Identifies if an error is an Axios-specific error. |