Hello react 👋,
Most projects on the web, including mobile apps needs to communicate with a REST API at some point. They use HTTP requests to communicate with APIs. One popular way of consuming these APIs in react can be done with AXIOS
Axios is a promise-based and lightweight JavaScript library used to make HTTP requests and can be used both in a node.js environment and in the browser. By using Axios it’s easy to send asynchronous HTTP request to REST endpoints and perform CRUD operations.
We can make get and post requests. Axios also has a powerful feature called Interceptors that allows us to modify our request or response before they reach their destination.
We are going to consume API from a dummy API - https://jsonplaceholder.typicode.com/users
In this article, we are going to be covering;
- GET requests with axios
- POST requests with axios
- Setting headers with axios
- Axios Interceptors
- Making multiple requests with axios
- Using async and await
Setting up axios in react
In order to use axios in our react app, we need to install and import it in our project. There are various ways to install axios, using npm, yarn, etc.
Using yarn
$ yarn add axios
Using npm
$ npm install axios
Using unpkg CDN
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
Using jsDelivr CDN
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
For the article we are going to use the npm package, In your terminal, run;
npx create-react-app my-app
cd my-app
npm start
When the new project has started running in the localhost, install axios using the npm package.
Making GET requests
In this section, we are going to get the names and usernames of users.
Inside the src
folder, create a new components
folder and make a User.js
file. Then import React and axios.
import React from 'react';
import axios from 'axios';
Now for this project we are going to use a class based component and initialize state.
class User extends React.Component {
state = {
persons: [],
}
}
export default User;
Next we will use a lifecycle method componentDidMount
, here we call axios.get(url)
which returns a promise that will resolve to either a response object or an error object.
We capture the response in res
.
componentDidMount() {
axios.get(`https://jsonplaceholder.typicode.com/users`)
.then(res => {
const persons = res.data;
this.setState({ persons });
})
.catch(err => {
console.log(err)
})
}
We capture the response and store it in res
retrieving the data in res.data
, which we store in const persons
.
Then setState
to persons, which updates this.state
We catch
any error that occurs and store it in err
which is a function and console.log()
the error statement.
Finally, we render
the data
render() {
return (
<>
{ this.state.persons.map(person =>
<div style={{borderBottom: "2px solid black"}} >
<p>NAME - {person.name}</p>
<p>BRED FOR - {person.username}</p>
</div>
)}
</>
)
}
}
We iterate through the response gotten from the API and then display in the render function. We dynamically add some styles to add a border bottom on each on each of the items gotten from the API response.
To make this show up in our browser, import the User.js
file in the App.js
file.
import User from "./components/User";
function App() {
return (
<div className="App">
<User />
</div>
);
}
export default App;
There are different response objects for when our request to the server is successfull.
- res.data payload returned from the server. By default, Axios expects JSON and will parse this back into a JavaScript object for you.
- res.status HTTP code returned from the server.
- res.statusText HTTP status message returned by the server.
- res.headers The headers sent back by the server.
- res.config The original request configuration.
- res.request It is the actual XMLHttpRequest object (when it is running in a browser)
Making POST requests
Now let us make post requests that allow us to add new users to the API.
Make a new file AddUser.js
in the components
folder.
We will create a form that allows for users input and a submit button that enables us to post to the API.
As usual, import react and axios, then create a class based component.
import React from 'react';
import axios from 'axios';
class AddUser extends React.Component {
state = {
NewPerson: [],
}
}
export default NewPerson
Let us add a handleChange
function, which captures the value of the input field in the form in the setState
and updates the state
.
handleChange = event => {
this.setState({ NewPerson: event.target.value });
}
Then add a handleSubmit
function, which submits the form
handleSubmit = event => {
event.preventDefault();
const user = {
NewPerson: this.state.NewPerson
};
axios.post(`https://jsonplaceholder.typicode.com/users`, { user })
.then(res => {
console.log(res);
console.log(res.data);
})
}
In the handleSubmit function, you prevent the default action of the form. Then update the state to the user input.
When using the post
request, we get the same response object with information that can be used inside the then
call.
we capture the user input which is then put along the post
request. We console.log
the response because we won't actually modify the API.
Add, the render
function that has the form, which makes all this work
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
Person Name:
<input type="text" name="name" onChange={this.handleChange} />
</label>
<button type="submit">Add</button>
</form>
</div>
)
}
}
Lastly we import it to our App.js
file.
import User from "./components/User";
import AddUser from "./components/AddUser";
function App() {
return (
<div className="App">
<AddUser />
<User />
</div>
);
}
export default App;
Setting headers with axios
When using an API, it is recommended to go through it's documentation as most APIs have different ways of implementaion.
An API, could require headers. Headers are a key–value pair in clear-text string format separated by a colon.
{
"key1": "value1",
"key2": " value2",
}
An API could require you to specify that the content type should be in JSON
format.
const config = { headers: { "Content-type": "application/json"}}
Then pass in the object containing the headers as the last argument.
axios.get(`https://api.thedogapi.com/v1/breeds`, config)
Axios Interceptors
Axios Interceptor is a function that gets called for every HTTP request made and response received by our application. Interceptors transforms/updates each requests before sending it and checks/filters the response before returning it. There are two types of interceptors: request interceptors and response interceptors. They both have 2 callback functions.
How Interceptors work
It is ideal, to put our interceptors in the index.js
file, incase we have much files we are working with axios and we dont want to repeat the Interceptors in each file.
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import axios from "axios";
//CODE GOES HERE
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
For instance, we want to show/hide loading statement on every call. and an error message if there is one;
//AN INTERCEPTOR FOR EVERY REQUEST WE SEND
axios.interceptors.request.use(function(config) {
console.log('Start Ajax Call');
return config;
}, function(error) {
console.log('Error');
return Promise.reject(error);
});
//AN INTERCEPTOR FOR RESPONSE WE GET
axios.interceptors.response.use(function(response) {
console.log('Done with Ajax call');
return response;
}, function(error) {
console.log('Error fetching the data');
return Promise.reject(error);
});
For every response we get, we can check for status code and work with it.
axios.interceptors.response.use(function(response) {
if (res.status === 201) {
console.log('Successfull');
}
if(res.status === 404) {
console.log("Not Found")
}
return response;
}, function(error) {
console.log('Error fetching the data');
return Promise.reject(error);
});
Making multiple requests with axios
With axios, we can make multiple HTTP requests and handle them simultaneously. We use the axios.all()
method which takes in an array of arguments and return single promise object that only resolves when all the arguments passed in the array have been resolved.
componentDidMount() {
axios.all([
axios.get(`https://jsonplaceholder.typicode.com/users`),
axios.get(`https://jsonplaceholder.typicode.com/posts`)
])
.then(response => {
console.log(response[0])
console.log(response[1])
});
}
Using async and await
We can use async
and await
to work with promises. await
resolves the promise and returns a value which is then assigned to a variable.
.then()
is replaced and the promise is resolved with the value stored inside the response
variable.
async componentDidMount() {
const response = await axios.get(`https://jsonplaceholder.typicode.com/users`)
console.log(response.data)
}
Notice that the code is cleaner now.
We have seen multiple ways axios can be used in our react application to create HTTP requests and handle responses and why it is a better approach than using a normal fetch API
Source code at Github