Fetching Data in Your React Application

React is arguably the most popular library for building interactive web applications. However, React is not a full-fledged web framework. It focuses on the view part of the venerable MVC model. 

There is a whole React ecosystem that addresses other aspects. In this tutorial, you'll learn about one of the most basic elements of any web application—how to fetch data to display. This is not trivial. There are several places in the React component hierarchy where you can fetch data. When to fetch data is another concern. You also need to consider what technology to use for fetching your data and where to store it. 

At the end of this tutorial, you'll have a clear picture of how data fetching works in React, the pros and cons of different approaches, and how to apply this knowledge to your React applications.

Getting Started

Let's create a skeleton for our React app with create-react-app:

> create-react-app react-data-fetcher

The result is a pretty elaborate directory structure. Read the excellent README file if you're unfamiliar with create-react-app.

Creating a Simple Server

I created a simple server for storing and serving quotes. It is not the focus of this tutorial, and its role is to provide a remote API for demonstrating how to fetch data with React. Just to satisfy your curiosity, it is a Python 3 application based on the hug framework and uses Redis as persistent storage. 

The API is extremely simple. There is a single endpoint, /quotes. It returns all the stored quotes in response to an HTTP GET request, and you can add new quotes by sending an HTTP POST request.

The full source code is available on GitHub.

Demo App Overview

The demo app is a React application that communicates with the quote service, displays all the quotes, and lets you add new quotes. 

Here is a screenshot:

A screenshot of the demo application

The app structure is very simple. I started with a skeleton created by create-react-app and added two components in the src sub-directory: QuoteList and AddQuoteForm. Here is the directory structure (excluding node_modules):

The full source code is available on GitLab.

Displaying Quotes

The QuoteList functional component displays a list of quotes as a bullet list. It expects an array of strings:

It is a child component of the main App component.

Fetching Data With the Fetch API

The fetch API is a promise-based API that returns a response object. In order to get to the actual JSON content, you need to invoke the json() method of the response object.

Placing Your Data-Fetching Code

React is, of course, all about components. The question of where to place data-fetching code is important. If you factor your code well, you'll have a lot of generic components and some application-specific components. React and JavaScript in general are very flexible, so it is possible to inject logic anywhere. 

Fetching quotes from a REST API requires some form of polling, since I want the quotes to be always up to date. But the initial fetch is also important. React components have lifecycle methods where you can implement logic that will execute at a particular time. The componentDidMount() method fires when the component can be accessed and its state modified. It is the perfect spot to initiate data fetching. 

Here is what it looks like:

If you really want to cut down on the time to first view, you may consider using the componentWillMount() to initiate your async fetching, but you risk having the fetch complete before the component is mounted. I don't recommend this approach.

Check out Mastering the React Lifecycle Methods for further details.

Choosing How Often to Fetch Data

The initial fetch in componentDidMount() is great, but I want to update the quotes frequently. In a REST-based API, the only solution is to periodically poll the server. The quote service is very basic and always returns all the quotes. 

More scalable services will provide a way to check for updates or even using HTTP if-modify-since or eTag. Our demo application just fetches everything every five seconds by starting a timer in componentDidMount() and cleaning up in componentWillUnmount():

The polling duration is an app-specific decision. If you need real-time updates and/or polling is stressing the back end too much, consider using WebSockets instead of REST.

Dealing With Long-Running Data Fetching

Sometimes data fetching can take a long time. In that case, displaying a progress bar or a shiny animation to let the user know what's going on can contribute a lot to the user experience. This is especially important when the user initiates the data fetching (e.g. by clicking a search button). 

In the demo app, I simply display a message saying "Fetching quotes..." while a fetch is ongoing. In the render() method of the main App component, I utilize conditional rendering by checking the state.isFetching member. 

The fetchQuotes() method takes care of updating state.isFetching by initializing it to true when it starts and setting it back to false when receiving the quotes:

Handling Errors

I do the very minimum of error handling here by logging caught errors to the console. Depending on your application, you may invoke some retry logic, notify the user, or display some fallback content.

Fetch API vs. Axios

The fetch API has a couple of gotchas. It requires the extra step of extracting the JSON from a response. It also doesn't catch all errors. For example, 404 will be returned as a normal response. You'll have to check the response code and also deal with network errors that are getting caught. 

So you'll have to deal with errors in two places. But you can use the axios.js library to address these issues and have slightly more concise code at the price of adding an external dependency. Here is what the code looks like with axios:

This doesn't look like much, but it helps. The code to add a new quote is much more concise with axios. Here is the fetch version:

And here is the axios version:

Conclusion

In this tutorial you learned how to fetch data asynchronously in a React application. We discussed the relevant lifecycle methods, polling, progress reporting, and error handling. 

We looked at two promise-based libraries: the fetch API and axios.js. Now, go out there and build awesome React applications that access remote APIs.

Over the last couple of years, React has grown in popularity. In fact, we have a number of items in the marketplace that are available for purchase, review, implementation, and so on. If you’re looking for additional resources around React, don’t hesitate to check them out.

Categories: