How to Implement REST APIs in React
This article provides a practical guide on how to integrate and consume REST APIs in a React application. You will learn how to fetch data using the native Fetch API and the popular Axios library, manage component state for loading and errors, and implement modern data-fetching best practices.
1. Using the Native Fetch API
The simplest way to consume a REST API in React is by using the
browser’s built-in fetch API inside the
useEffect hook. This method requires no external
dependencies.
import React, { useState, useEffect } from 'react';
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then((data) => {
setUsers(data);
setLoading(false);
})
.catch((error) => {
setError(error.message);
setLoading(false);
});
}, []);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
export default UserList;2. Using Axios for API Requests
Axios is a popular promise-based HTTP client that simplifies API
requests. It automatically transforms JSON data and has built-in
protection against XSRF. To use it, first install it via npm:
npm install axios.
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function PostList() {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
axios.get('https://jsonplaceholder.typicode.com/posts')
.then((response) => {
setPosts(response.data);
setLoading(false);
})
.catch((error) => {
setError(error.message);
setLoading(false);
});
}, []);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<ul>
{posts.slice(0, 5).map(post => (
<li key={post.id}>
<strong>{post.title}</strong>
<p>{post.body}</p>
</li>
))}
</ul>
);
}
export default PostList;3. Handling POST, PUT, and DELETE Requests
In addition to fetching data (GET), you often need to send data to a REST API. Below is an example of implementing a POST request using Axios to add a new resource.
import React, { useState } from 'react';
import axios from 'axios';
function CreatePost() {
const [title, setTitle] = useState('');
const [body, setBody] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await axios.post('https://jsonplaceholder.typicode.com/posts', {
title,
body,
userId: 1,
});
console.log('Post Created:', response.data);
alert('Post created successfully!');
} catch (error) {
console.error('Error creating post:', error);
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Title"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<textarea
placeholder="Body"
value={body}
onChange={(e) => setBody(e.target.value)}
/>
<button type="submit">Submit</button>
</form>
);
}
export default CreatePost;4. Modern Approach: React Query (TanStack Query)
For large-scale production applications, manual state management for
APIs using useEffect can become complex. React Query is the
industry standard for managing server state. It handles caching,
background updates, and stale data automatically.
To use it, install the library:
npm install @tanstack/react-query.
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
const fetchUsers = async () => {
const { data } = await axios.get('https://jsonplaceholder.typicode.com/users');
return data;
};
function UsersWithQuery() {
const { data, error, isLoading } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
});
if (isLoading) return <p>Loading...</p>;
if (error) return <p>An error occurred: {error.message}</p>;
return (
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
export default UsersWithQuery;