At some point in your journey of learning React, you’ll get to the point where you want a component to consume an API. Or maybe you want to connect your app to a REST backend, you name it. After all, you want that flippin’ data from that server in your app.
But how do you get the data from an API or your backend into your component?
It’s Not React!
First of all: Fetching data from an API is not a React specific concept.
React doesn’t care about the libraries you use, or how you load data from a Server. At the end, it’s plain JavaScript. Do you know how to fetch data into a vanilla JavaScript app? Well, then you already know how to do that with your React app.
In the following sections, you’re going to learn how to:
- Fetch data from a REST API
- Where to do an API call in React
- Handle Response Data in your Component
Fetch Data From a REST API
To fetch data from a REST API, you have to perform an AJAX request. Specifically, a GET request. If you prefer the full vanilla style, you would do that by creating an XMLHttpRequest. See the example from developer.mozilla.org:
function reqListener () {
console.log(this.responseText);
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "http://www.example.org/example.txt");
oReq.send();
Thankfully, there are tools out there that are much easier to use. One of those libraries is axios, which I’m using in most of my projects and examples. It is based on promises, which makes working with AJAX Requests a lot easier. See the examples for a GET Request from the axios GitHub Repository:
You can either work with the Promise syntax:
axios.get('/user?ID=12345')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
Or if you’re more comfortable with async and await:
async function getUser() {
try {
const response = await axios.get('/user?ID=12345');
console.log(response);
} catch (error) {
console.error(error);
} }
And that’s how you perform a GET request with axios. Now let’s see how you can use that inside a React component.
Where to Load Data From an API in React
Whenever you have to load data into a React app, you should consider doing that in the componentDidMount
lifecycle method.
Why? Because you want to use setState
to store the data inside your component’s state as soon as the response returns.
But let’s have a look at a real example. In the next section you’ll see a real component fetching data from a REST API from within componentDidMount
.
Handle Response Data in Your Component
First, have a look at this example, that I based on the official docs:
import React, { Component } from "react";
import axios from 'axios';
export default class MyComponent extends Component {
state = {
error: null,
isLoaded: false,
items: []
};
componentDidMount() {
axios.get("https://jsonplaceholder.typicode.com/users").then(
result => {
this.setState({
isLoaded: true,
items: result.data
});
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
error => {
this.setState({
isLoaded: true,
error
});
}
);
}
render() {
const { error, isLoaded, items } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<ul>
{items.map(item => (
<li key={item.username}>
{item.username}: {item.name}
</li>
))}
</ul>
);
}
}
}
In the above example, we’re fetching a list of users from https://jsonplaceholder.typicode.com/users.
Initially isLoaded
is set to false. This is important, if you want to show a loading indicator while your component is fetching the data. As soon as the result is here, we have to put the returned data from result.data
into the state of our component and set isLoaded
to true. Now the component displays our users instead of the loading indicator.
Wrapping Up
Now you’ve learned how to fetch data from a REST API into your React App.
Always remember:
- fetching data or communicating with APIs is not specific to React
- data loading happens inside
componentDidMount
Need more help calling an API from your React App? Leave a comment below or send me an email at hi@andreasreiterer.at – I’m always happy to help!
Your work is much appreciated and i give you high ‘kudos’ for providing insights to complex code logic. You’ve been of tremendous help to me and i’m now an avid follower.
Thank you very much for the kind words 🙂 If there’s anything I can help you with, don’t be afraid to ask.
Thank you for the great post.
Perhaps adding the
import axios from "axios";
can help people who want to try to code in their environments.Thanks for the feedback! I just added the import to the code snippet.
Hi Andreas,
I really want to be able to render that data. Though I’m used to rendering the data from a separate React class file via the HTML DOM and don’t know how to render it any other way using your code.
So in the react file I’m doing this at the very end…
//MyComponent.js
ReactDOM.render(React.createElement(ApiCall, null), document.getElementById(‘api-call-example’));
//END MyComponent.js
And in HTML I’m specifying the script output div and loaded the React component.
//index.html
http://scripts/ApiCall.js
//END index.html
All other specified scripts in the html file are working except for that one. Do you know of any other way I could see the data, please or what I should be looking at in the mean time to just render the data?
Let me know if possible. Thanks.
Jordan
Ahh my apologies. I got it working fine, thank you. Of course you meant the Create-React-App where you put the tag
in the function called App in App.js.
Hi Andreas, thank you for another great concept and a working snippet.
I’m wondering how would you approach triggering POST requests in a HOC?
why not
fetch(‘http://example.com/movies.json’)
.then(response => response.json())
.then(data => console.log(data));
???
it’s simpler! see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
this is a excellent work where this code works out of box and self explanatory.