Axios is among the most popular promise based HTTP clients for both browsers and Node.js. At the time of writing this article, it’s floating at around 4 million weekly downloads on NPM only.
It’s simple, lightweight and easy to customize. Not only that, but works great with React and many other frameworks.
Axios provides support for request and response interceptors, transformers and auto-conversion to JSON. It’s also protecting you by default against cross-site request forgery (XSRF).
βοΈ Here's everything you need to know about using Axios with React! #axios #react Click To Tweet
In this short tutorial, we’ll cover:
- How to integrate and configure Axios in your React project
- Where to make async requests in React
- Using Async/Await and error handling
- How to make GET requests
- How to make POST requests
- How to make PATCH requests
- How to make DELETE requests
Before we start, let’s create a new project using create-react-app. The process is very straightforward.
# Create a new app.
create-react-app axios-react-tutorial
# Move inside our new project.
cd axios-react-tutorial
# Install dependencies.
yarn add axios shards-react
# Start the project.
yarn start
Once you start the project, you should see the default React welcome page:
We’ll need only Axios and Shards React as our dependencies. We’ll use the Shards React UI kit to make our UI data look sleek. π
Next, open the project in your favourite editor, and let’s dive right in! πββοΈ
Integrating and configuring Axios in your React project
By default, our project is pretty empty. We’ll fix this by creating a new directory called utils
. Inside, let’s also create a new file called API.js
in which we’ll store our Axios configuration.
// utils/API.js
import axios from "axios";
export default axios.create({
baseURL: "https://randomuser.me/api/",
responseType: "json"
});
The code inside API.js
imports Axios and exports a new configured instance of it. It’s set up to use the RandomUser API as a base URL and also specify that we’d like JSON in return.
Finally, you can create a new file User.js
and inside paste the following component. The User
component will serve as our user placeholder card.
import React from "react";
import PropTypes from "prop-types";
import "bootstrap/dist/css/bootstrap.min.css";
import "shards-ui/dist/css/shards.min.css";
import { Card } from "shards-react";
class User extends React.Component {
render() {
const { name, avatar, email, isLoading } = this.props;
const userDetails = (
<div>
<img
className="img-thumbnail rounded-circle mx-auto mb-2 shadow-sm"
src={avatar}
alt={name}
style={{ width: "100px", height: "100px" }}
/>
<h4 className="mb-0">{name}</h4>
<span className="text-muted">{email}</span>
</div>
);
const loadingMessage = <span className="d-flex m-auto">Loading...</span>;
return (
<Card
className="mx-auto mt-4 text-center p-5"
style={{ maxWidth: "300px", minHeight: "250px" }}
>
{isLoading ? loadingMessage : userDetails}
</Card>
);
}
}
User.propTypes = {
name: PropTypes.string,
avatar: PropTypes.string,
email: PropTypes.string,
isLoading: PropTypes.bool
};
export default User;
The User
component is a simple component that displays a user avatar, his or her name and email inside a card. It accepts an isLoading
boolean prop, which if is set to true
it will display a Loading...
message. Otherwise, it will display the actual user details.
Next, open src/App.js
and delete everything inside. We won’t need it anyway.
Let’s use this opportunity to see how our User card looks like with some plain data.
// src/App.js
import React from "react";
class App extends React.Component {
render() {
return <User name="Jessica Doe" avatar="..." email="hello@jessica.com" />;
}
}
export default App;
Make sure to provide an image URL to your avatar prop.
This looks good so far, but let’s load some “real” fake data using an asynchronous request and see how that goes.
In which lifecycle hook should we make our request?
Ok, we have a component, but where should we make the actual request to our API to load the data? The answer is inside the componentDidMount()
lifecycle hook.
Based on the official React documentation, this is the perfect place for such an action.
If you need to load data from a remote endpoint, componentDidMount()
is a good place to make requests.
Perfect! Now that we know where we should load our data, let’s make our first GET request. But first, let’s update our App.js
component so we can integrate the request logic.
// src/App.js
import React from "react";
import API from "./utils/API";
import User from "./User";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
name: null,
avatar: null,
email: null
};
}
render() {
const { isLoading, name, avatar, email } = this.state;
return (
<User isLoading={isLoading} name={name} avatar={avatar} email={email} />
);
}
async componentDidMount() {
// Load async data.
// Update state with new data.
// Re-render our component.
}
}
export default App;
GET Requests
Now the App.js
component has its own state. That will help with keeping track of the loading state, the person’s name, avatar and email. It’s also using the state data to hydrate the User
component when the component is re-rendered.
We also created the async componentDidMount()
method. Inside, we make an asynchronous request to load the data and update our component’s state. That will trigger a new re-render.
Notice that the method is async
which will allow us to await
certain actions inside.
Finally, let’s update the method to GET tge data from the remote server.
// src/App.js
// ...
async componentDidMount() {
// Load async data.
let userData = await API.get('/', {
params: {
results: 1,
inc: 'name,email,picture'
}
});
// Parse the results for ease of use.
userData = userData.data.results[0];
// Update state with new data and re-render our component.
const name = `${userData.name.first} ${userData.name.last}`;
const avatar = userData.picture.large;
const email = userData.email;
this.setState({
...this.state, ...{
isLoading: false,
name,
avatar,
email
}
});
}
// ...
export default App;
That’s a lot of code, let’s break it down step by step:
// ...
let userData = await API.get("/", {
params: {
results: 1,
inc: "name,email,picture"
}
});
// ...
Inside the async componentDidMount()
method, we are making an asynchronous GET request. We’re making this request off the base URL only (notice the forward slash /
). We’re also sending two params, specifying how many results and which details we expect. In this case it’s the name, email and avatar.
// ...
userData = userData.data.results[0];
// ...
When the action completes, we store the data inside the userData
variable. Next, we update the variable with the returned data for ease of use.
Finally, we create easy to use variables (name, avatar, email) and update the state with their values.
Handling Errors with Async/Await
The usual way of handling errors in JavaScript when using promises, is via the .catch()
method. The beauty of using async/await
is thet we can forget about that and use try/catch
statements instead.
Here’s how the request above would be rewritten using try/catch
. The request is also adjusted so it will fail.
// ...
try {
// Load async data from an inexistent endpoint.
let userData = await API.get("/inexistent-endpoint");
} catch (e) {
console.log(`π± Axios request failed: ${e}`);
}
// ...
And of course we get the error logged in our console.
The catch
block is the perfect place to parse the returned error. It’s also a great place to show your users an appropriate feedback message.
Using Mockable to mock our other requests
We now know how almost everything works in Axios. We can now break away from our example and explore other Axios methods in more depth. In the next part of the tutorial, we’ll do so without focusing on presentation.
For this to work, we can use Mockable, a free REST API mocking tool that we can configure as we wish.
Using Mockable I was able to mock the other three request types we will explore in this article: POST, PATCH and DELETE. You can download my mock REST api here so you can use it as a starting point.
Using the mock API, I am able to make the following requests using Axios:
- πββοΈ POST β http://demo0725191.mockable.io/post_data
- π PATCH β http://demo0725191.mockable.io/patch_data
- βοΈ DELETE β http://demo0725191.mockable.io/delete_data
POST Requests
In Axios, you can create POST requests using the .post()
method and passing the data as a second parameter. Here’s the method’s signature for your reference.
axios.post(url[, data[, config]])
Using the mocked endpoint above, our POST request would become:
import axios from "axios";
try {
const response = await axios.post('http://demo0725191.mockable.io/post_data', { posted_data: 'example' });
console.log('π Returned data:', response);
} catch (e) {
console.log(`π± Axios request failed: ${e}`);
}
And the returned response shows that the data has been successfully POSTed.
PATCH Requests
PATCH requests are also extremely similar and can be created using the .patch()
method. Here’s the signature for your reference:
axios.patch(url[, data[, config]])
Using the mocked endpoint above, our PATCH request becomes:
import axios from "axios";
try {
const response = await axios.patch('http://demo0725191.mockable.io/patch_data', { new_name: 'My new cool name!' });
console.log('π Returned data:', response);
} catch (e) {
console.log(`π± Axios request failed: ${e}`);
}
And the data is successfully updated when our request finished.
DELETE Requests
I guess that it goes without saying that DELETE requests are also easy and can be created using the .delete()
method. Here’s the signature for your reference.
axios.delete(url[, config])
Using the mocked endpoint above, our DELETE request becomes:
import axios from "axios";
try {
const response = await axios.delete('http://demo0725191.mockable.io/delete_data');
console.log('π Returned data:', response);
} catch (e) {
console.log(`π± Axios request failed: ${e}`);
}
And the data is successfully deleted from our mocked server:
Conclusion
Handling requests in React with Axios is very easy to understand. There’s room for improvement, like adding more abstractions and structure, but that’s for another time.
What do you think about using React and Axios? Are there any certain features do you think I missed or should be covered? Let me know in the comments below!
Also, if you liked the article, make sure to share it with your friends!
βοΈ Here's everything you need to know about using Axios with React! #axios #react Click To Tweet
π€ What do you think?