One of the first questions new React developers have is, “How do I do AJAX requests in React?” a.k.a. “How do I make API calls in React?”
Here’s an answer to that question.
First: React itself doesn’t have any allegiance to any particular way of fetching data. In fact, as far as React is concerned, it doesn’t even know there’s a “server” in the picture at all.
React simply renders components, using data from only two places: props and state.
So therefore, to use some data from the server, you need to get that data into your components’ props or state.
You can complicate this process with services and data models (er, “build abstractions”) as much as you desire, but ultimately it’s just components rendering props and state.
Choose an HTTP Library
To fetch that data from the server, you’ll need an HTTP library. There are a ton of them out there. Ultimately they all do the same thing, but they have different features.
Like promises? Go with axios.
Hate promises, but love callbacks? Take a look at superagent.
Rather use something soon-to-be-standardized? fetch might be your favorite.
The thing is, it doesn’t really matter. There’s no “best.”
Some will say that fetch
is the best because it’s part of the standard, but despite that, there are still competing HTTP libraries that many people continue to use and prefer. So use what you like.
I like axios and I think React and Axios pair nicely together, so that’s what I’ll show here. But seriously, if you don’t like it for some reason, go look at one of the other options.
Fetch The Data With Axios and React
Here’s a simple example component that fetches the posts from a subreddit (/r/reactjs
in this case). Take a look at it, and we’ll go over how it works.
How It Works
First, we import the axios
library:
We’re initializing state at the top using a class property. You can also write this using a constructor, and they’re functionally equivalent. I like the class property because it’s just less code to write.
componentDidMount
is where the magic happens. This method will be executed when the component “mounts” (is added to the DOM) for the first time. This method is only executed once during the component’s life.
TL;DR: Fetch server data in the componentDidMount
lifecycle method
It uses the axios.get
function to fetch the data from the subreddit, based on the subreddit
prop passed in during render at the bottom. The backticks are an ES6 template string, and it probably does what you think: the ${...}
part is replaced by the value of that expression, so the URL passed to axios.get
is actually http://www.reddit.com/r/reactjs.json
.
Two things to note here, specific to Reddit:
-
You can tack on
.json
to the end of any subreddit URL and get a JSON representation of the posts there. -
If you forget the
www
you’ll get a CORS error (at least, I did).
Since Axios uses promises, we chain the call with .then
to handle the response. The posts
are extracted after a little bit of transformation, and then the important bit:
The component’s state is updated by calling this.setState
with the new array of posts. This triggers a re-render, and then the posts are visible.
That’s all there is to it!
Bonus: Loading Indicator
Can you think of how to modify the code to add a “Loading…” message while the request is in flight?
Hint: set a flag in state that will toggle once the request completes. Use that flag in the render function to show the loading indicator.
Download the Example Code
I put together the example code with the bonus Loading Indicator and included unit tests too. You can download it right here, no email required or anything:
Unzip it, run npm install
, then npm start
.
Translations
- Russian translation of this article by GetColorings
- Deutsche by Philipp Egger