Axios and React with state, data & error handling.

Fredrick Mbugua
5 min readMar 22, 2023

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.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Fredrick Mbugua
Fredrick Mbugua

Written by Fredrick Mbugua

Software Developer @Safaricom. Experienced in Web, Mobile (Flutter & Kotlin), CrytpoCurrency, Smart Contracts, API and Software Design, Interaction Design

No responses yet

Write a response