React JS: API Integration - Using Axios
Introduction
Integrating with APIs is a fundamental aspect of modern web development. React, being a front-end library, often needs to fetch data from and send data to back-end servers. Axios is a popular, promise-based HTTP client that simplifies making these requests. This document will guide you through integrating APIs in your React application using Axios.
Prerequisites
- Node.js and npm (or yarn) installed: Ensure you have Node.js and its package manager installed on your system.
- Basic React knowledge: Familiarity with React components, state, and lifecycle methods (or hooks) is assumed.
- An API to work with: For demonstration, we'll use a public API like JSONPlaceholder. You can substitute this with your own API.
Installing Axios
First, install Axios into your React project using npm or yarn:
npm install axios
# or
yarn add axios
Making GET Requests
The most common API interaction is fetching data using a GET request. Here's how to do it using Axios within a React component:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function DataFetcher() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1');
setData(response.data);
setLoading(false);
} catch (error) {
setError(error);
setLoading(false);
}
};
fetchData();
}, []); // Empty dependency array ensures this effect runs only once on mount
if (loading) {
return <p>Loading...</p>;
}
if (error) {
return <p>Error: {error.message}</p>;
}
return (
<div>
<h1>{data.title}</h1>
<p>{data.body}</p>
</div>
);
}
export default DataFetcher;
Explanation:
- Import Axios:
import axios from 'axios';imports the Axios library. - State Variables:
data: Stores the fetched data. Initialized tonull.loading: Indicates whether the data is being fetched. Initialized totrue.error: Stores any error that occurs during the fetch. Initialized tonull.
useEffectHook: This hook is used to perform side effects (like API calls) in functional components.- The empty dependency array
[]ensures the effect runs only once when the component mounts.
- The empty dependency array
fetchDataFunction:- An
asyncfunction to handle the API call. axios.get('https://jsonplaceholder.typicode.com/posts/1'): Makes a GET request to the specified URL. Axios returns a Promise.await: Pauses execution until the Promise resolves (the API call completes).response.data: The actual data returned by the API is accessed throughresponse.data.setData(response.data): Updates thedatastate with the fetched data.setLoading(false): Setsloadingtofalseto indicate the data has been loaded.- Error Handling: The
try...catchblock handles potential errors during the API call. If an error occurs, it updates theerrorstate and setsloadingtofalse.
- An
- Conditional Rendering: The component renders different content based on the
loadinganderrorstates.
Making POST Requests
To send data to an API (e.g., creating a new resource), use a POST request.
import React, { useState } from 'react';
import axios from 'axios';
function PostCreator() {
const [title, setTitle] = useState('');
const [body, setBody] = useState('');
const [success, setSuccess] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await axios.post('https://jsonplaceholder.typicode.com/posts', {
title: title,
body: body,
userId: 1,
});
console.log('Post created:', response.data);
setSuccess(true);
setTitle('');
setBody('');
} catch (error) {
console.error('Error creating post:', error);
setSuccess(false);
}
};
return (
<form onSubmit={handleSubmit}>
<label>
Title:
<input type="text" value={title} onChange={(e) => setTitle(e.target.value)} />
</label>
<br />
<label>
Body:
<input type="text" value={body} onChange={(e) => setBody(e.target.value)} />
</label>
<br />
<button type="submit">Create Post</button>
{success && <p>Post created successfully!</p>}
</form>
);
}
export default PostCreator;
Explanation:
axios.post(): Makes a POST request to the specified URL.- Data Payload: The second argument to
axios.post()is the data you want to send to the API. It's typically an object. - Form Handling: The component includes a form to collect user input (title and body).
handleSubmitFunction: Handles the form submission.- Success State: The
successstate variable indicates whether the post was created successfully.
Other HTTP Methods
Axios supports other HTTP methods as well:
axios.put(): Used to update an existing resource.axios.patch(): Used to partially update an existing resource.axios.delete(): Used to delete a resource.
The usage is similar to axios.get() and axios.post(), with the appropriate method and potentially a data payload.
Axios Configuration
Axios allows you to configure default settings for your requests. This can be useful for setting base URLs, headers, or authentication tokens.
// axiosConfig.js
import axios from 'axios';
const instance = axios.create({
baseURL: 'https://jsonplaceholder.typicode.com',
timeout: 10000, // 10 seconds
headers: {
'Content-Type': 'application/json',
},
});
export default instance;
Then, in your component:
import React from 'react';
import axiosConfig from './axiosConfig';
function MyComponent() {
const fetchData = async () => {
try {
const response = await axiosConfig.get('/posts/1'); // Uses the configured baseURL
console.log(response.data);
} catch (error) {
console.error(error);
}
};
// ...
}
Interceptors
Axios interceptors allow you to intercept requests or responses before they are handled. This is useful for tasks like adding authentication headers or logging requests.
// interceptors.js
import axios from 'axios';
axios.interceptors.request.use(
(config) => {
// Add authentication token to every request
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
axios.interceptors.response.use(
(response) => {
return response;
},
(error) => {
// Handle global error handling (e.g., redirect to error page)
return Promise.reject(error);
}
);
Import this file in your main application file (e.g., index.js) to apply the interceptors globally.
Best Practices
- Error Handling: Always include proper error handling using
try...catchblocks. - Loading States: Provide visual feedback to the user while data is being fetched (e.g., a loading spinner).
- Data Validation: Validate the data received from the API to ensure it's in the expected format.
- Security: Be mindful of security best practices when handling sensitive data. Never hardcode API keys or credentials directly into your code. Use environment variables.
- Cancellation: For long-running requests, consider using Axios's