Axios and React with state, data & error handling.

Axios is a popular JavaScript library used for making HTTP requests from web applications. It is widely used in React applications, as it provides an easy-to-use interface for handling API calls. In this article, we will start by implementing Axios in a simple React application and gradually move on to more complicated use cases.
Getting Started with Axios in React
To get started with Axios in a React application, we need to first install the Axios library using npm. You can do this by running the following command in your terminal:
npm install axios
Once Axios is installed, we can import it in our React component and start using it to make API calls. Here’s an example of how to do this:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [data, setData] = useState([]);
useEffect(() => {
axios.get('https://jsonplaceholder.typicode.com/users')
.then(response => {
setData(response.data);
})
.catch(error => {
console.log(error);
})
}, []);
return (
<div>
<h1>User List</h1>
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
}
export default App;
In this example, we’re using the useEffect
hook to make an API call to the JSONPlaceholder API and fetch a list of users. We're then storing the data in the component's state using the useState
hook and rendering it to the screen.
Handling Errors and Loading States
When making API calls, it’s important to handle errors and show a loading state to the user while waiting for the response. Let’s update our example to include these features:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
const [data, setData] = useState([]);
useEffect(() => {
axios.get('https://jsonplaceholder.typicode.com/users')
.then(response => {
setData(response.data);
setLoading(false);
})
.catch(error => {
setError('Error retrieving data');
setLoading(false);
})
}, []);
if (loading) return <p>Loading...</p>;
if (error) return <p>{error}</p>;
return (
<div>
<h1>User List</h1>
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
}
export default App;
In this updated example, we’re using the loading
and error
state variables to display a loading message or an error message to the user, depending on the state of the API call. We’re also setting the loading
state to false
once we've received the data or encountered an error, to indicate that the API call has completed.
Adding Query Parameters to API Calls
Often, when making API calls, we need to include query parameters to specify the data we want to retrieve. Axios makes it easy to include query parameters in our API calls using the params
option. Let's update our example to include a query parameter to filter the list of users by name:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
const [data, setData] = useState([]);
useEffect(() => {
axios.get('https://jsonplaceholder.typicode.com/users', {
params: {
name: 'Leanne Graham'
}
})
.then(response => {
setData(response.data);
setLoading(false);
})
.catch(error => {
setError('Error retrieving data');
setLoading(false);
})
}, []);
if (loading) return <p>Loading...</p>;
if (error) return <p>{error}</p>;
return (
<div>
<h1>User List</h1>
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
}
export default App;
In this example, we’re including the params option in our axios.get
call to specify the name
query parameter, which filters the list of users to only include the user with the name “Leanne Graham”. We’re using the same useEffect
hook to make the API call, and handling loading and error states as before.
Posting Data to an API
In addition to retrieving data from APIs, we can also use Axios to post data to an API. Let’s update our example to include a form that allows users to add new users to the list:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
const [data, setData] = useState([]);
const [name, setName] = useState('');
const [username, setUsername] = useState('');
useEffect(() => {
axios.get('https://jsonplaceholder.typicode.com/users')
.then(response => {
setData(response.data);
setLoading(false);
})
.catch(error => {
setError('Error retrieving data');
setLoading(false);
})
}, []);
const handleSubmit = event => {
event.preventDefault();
const newUser = {
name: name,
username: username
};
axios.post('https://jsonplaceholder.typicode.com/users', newUser)
.then(response => {
setData([...data, response.data]);
setName('');
setUsername('');
})
.catch(error => {
setError('Error adding user');
});
};
if (loading) return <p>Loading...</p>;
if (error) return <p>{error}</p>;
return (
<div>
<h1>User List</h1>
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" value={name} onChange={e => setName(e.target.value)} />
</label>
<label>
Username:
<input type="text" value={username} onChange={e => setUsername(e.target.value)} />
</label>
<button type="submit">Add User</button>
</form>
</div>
);
}
export default App;
In this example, we’re using the useState
hook to store the name
and username
values entered by the user in the form. When the form is submitted, we're creating a new user object with these values and sending a POST request to the JSONPlaceholder API to add the user to the list. If the request is successful, we're updating the state of the component to include the new user, and clearing the form inputs.
Adding Headers and Authentication
In some cases, you may need to add headers to your API requests to provide authentication or authorization information. Axios makes it easy to add headers to your requests using the headers
option. Let's update our example to include a header with an authentication token:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
const [data, setData] = useState([]);
useEffect(() => {
axios.get('https://jsonplaceholder.typicode.com/users', {
headers: {
Authorization: 'Bearer myAuthToken'
}
})
.then(response => {
setData(response.data);
setLoading(false);
})
.catch(error => {
setError('Error retrieving data');
setLoading(false);
})
}, []);
if (loading) return <p>Loading...</p>;
if (error) return <p>{error}</p>;
return (
<div>
<h1>User List</h1>
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
}
export default App;
In this example, we’re including the headers
option in our axios.get
call to specify the Authorization
header with a bearer token. This can be used to authenticate the user with the API.
Note that the exact format and method of authentication will vary depending on the API you are using. Check the documentation of the API for information on how to authenticate your requests.
Conclusion
In this article, we’ve seen how to use Axios in a React application to make API calls, handle loading and error states, include query parameters, and post data to an API. We’ve also seen how to add headers to your requests to provide authentication or authorization information.
Axios is a powerful tool for interacting with APIs in your React applications, providing a simple and consistent way to make API requests and handle responses. With these techniques, you can build dynamic and responsive web applications that interact with APIs to provide rich and engaging user experiences.