How to Update REST APIs in React
Updating REST APIs in React involves sending HTTP mutation
requests—such as POST, PUT, or
PATCH—from your client-side application to a backend
server. This article covers the most effective ways to perform these
updates, demonstrating how to use the native Fetch API, the popular
Axios library, and modern data-fetching tools like TanStack Query (React
Query) to manage state, loading, and error conditions.
Choosing the Right HTTP Method
Before writing the React code, you need to use the correct HTTP method for your update:
- PUT: Replaces the entire target resource with the new payload.
- PATCH: Applies partial modifications to the resource.
- POST: Creates a new resource or occasionally triggers specific processing.
Method 1: Using the Native Fetch API
The native fetch() browser API is the simplest way to
update data without installing third-party packages. You trigger the API
call inside an event handler (like a button click or form submission)
and handle the promise.
import { useState } from 'react';
function UpdateUser({ userId }) {
const [name, setName] = useState('');
const [isLoading, setIsLoading] = useState(false);
const handleUpdate = async (e) => {
e.preventDefault();
setIsLoading(true);
try {
const response = await fetch(`https://api.example.com/users/${userId}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name }),
});
if (!response.ok) {
throw new Error('Failed to update user');
}
const data = await response.json();
alert('Update successful!');
} catch (error) {
console.error(error);
alert('An error occurred');
} finally {
setIsLoading(false);
}
};
return (
<form onSubmit={handleUpdate}>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="New Name"
/>
<button type="submit" disabled={isLoading}>
{isLoading ? 'Updating...' : 'Update Name'}
</button>
</form>
);
}Method 2: Using Axios
Axios is a popular HTTP client that simplifies the syntax, automatically transforms JSON data, and provides better error handling than the Fetch API.
To install Axios:
npm install axiosBelow is how you use Axios to perform a PUT request:
import { useState } from 'react';
import axios from 'axios';
function UpdateProduct({ productId }) {
const [price, setPrice] = useState('');
const updatePrice = async () => {
try {
const response = await axios.put(`https://api.example.com/products/${productId}`, {
price: parseFloat(price),
});
console.log('Success:', response.data);
} catch (error) {
console.error('Error updating price:', error.response?.data || error.message);
}
};
return (
<div>
<input
type="number"
value={price}
onChange={(e) => setPrice(e.target.value)}
placeholder="New Price"
/>
<button onClick={updatePrice}>Update Price</button>
</div>
);
}Method 3: Using TanStack Query (React Query)
For production applications, managing loading states, error states,
and cache synchronization manually becomes repetitive. TanStack Query
provides a useMutation hook designed specifically for
updating server data.
To install TanStack Query:
npm install @tanstack/react-queryHere is how you perform an update and automatically refresh the UI cache:
import { useMutation, useQueryClient } from '@tanstack/react-query';
import axios from 'axios';
const updateUserEmail = async ({ userId, email }) => {
const response = await axios.patch(`https://api.example.com/users/${userId}`, { email });
return response.data;
};
function UpdateEmailForm({ userId }) {
const queryClient = useQueryClient();
const [email, setEmail] = useState('');
const mutation = useMutation({
mutationFn: updateUserEmail,
onSuccess: () => {
// Invalidate and refetch the user data query to update the UI
queryClient.invalidateQueries({ queryKey: ['user', userId] });
alert('Email updated successfully!');
},
onError: (error) => {
console.error('Mutation error:', error);
}
});
const handleSubmit = (e) => {
e.preventDefault();
mutation.mutate({ userId, email });
};
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="New Email"
/>
<button type="submit" disabled={mutation.isPending}>
{mutation.isPending ? 'Saving...' : 'Update Email'}
</button>
{mutation.isError && <p>Error: {mutation.error.message}</p>}
</form>
);
}Key Best Practices for API Updates
- Implement Loading States: Always disable update buttons and show a loading spinner/text to prevent users from double-submitting forms.
- Handle Errors Gracefully: Do not assume your API calls will always succeed. Catch errors and show user-friendly error messages.
- Keep Client Cache Synchronized: If you update a resource, ensure your local React state or cache (like TanStack Query) updates as well to reflect the changes immediately.
- Secure Your Requests: Send authorization headers (such as Bearer tokens) if the API endpoints require authentication.