How to use the React Async Library for Declarative Data Fetching

How to use the React Async Library for Declarative Data Fetching

In this tutorial, we explored how to use the React-Async library to help us fetch data easily without any hassle. We also looked at some of the helper functions it offers and the philosophy behind it. React-Async is a powerful tool and has the potential to enhance developer experience.

In this tutorial, we explored how to use the React-Async library to help us fetch data easily without any hassle. We also looked at some of the helper functions it offers and the philosophy behind it. React-Async is a powerful tool and has the potential to enhance developer experience.

Generally, there are two ways of writing code: Imperatively/Declaratively and two ways of fetching Data: Synchronously/Asynchronously. We are more convenient with making requests imperatively using fetch or libraries like axios.

Table of Contents

  • Fetching Data Declaratively with React-Async
  • Helper Components
  • More Helper Functions

With async-await, we get an opportunity to move from imperative asynchronous to imperative synchronous code style for fetching data. React is a library that makes it easy to build UIs declaratively. The key word is declarative. This is why there is a mixed pattern when we have both imperative code (for data fetching) and declarative code (for UI composition).

React-async provides a declarative API to perform any REST API call easily using a single React component. It takes care of handling errors, promise resolution and retrying promises and an excellent job at dealing with local asynchronous state.

How to use the React Async Library for Declarative Data Fetching

Fetching Data Declaratively with React-Async

For better understanding let’s break down our topic into two parts. Declarative data fetching and Asynchronous API Calls in react.

Declarative data fetching is an approach used in calling APIS where you declare what you want it gets done for you without you worrying about all the things related to the call. It’s the opposite of the imperative approach where you also need to detail the steps, i.e. how to get what you need.

Since JavaScript is synchronous by default and is single threaded, when we want to render a component that shows some data coming from an asynchronous call before React 16, we were stuck with classes. We had to use the component lifecycle methods to ensure the call happens when the component is mounted, and then we use the local state to manage the loading state.

Asynchronous requests will wait for a request to respond while the rest of the code continues to execute. Then when the time is right, a callback will spring these asynchronous requests into action.

Let’s demonstrate this by making a call to an endpoint to grab a list of cryptocurrency prices.

import React, { Component } from 'react';
import axios from 'axios';

class App extends Component {
  state = {
    data: [],
    error: '',
  };

  componentDidMount() {     
    axios
      .get('https://api.coinmarketcap.com/v1/ticker/?limit=1')
      .then(res => this.setState({ data: res.data }))
      .catch(error => this.setState({ error }));
  }

  render () {
    return (

        {this.state.data.map(el => (* {el.name}: {el.price_usd}
))}

    );
  }
}

export default App;

N/B: Install axios by typing ‘npm install axios` in your terminal

Here we make our API call in the componentDidMount function to ensure it runs as soon as the component is loaded. We can make sense of our data only after we go through the following steps:

  • First, we make a request to the API
  • We receive a response
  • We extract data from the response
  • Then store the data in our local state

In the event of an error during the data fetching process:

  • We catch the error
  • Store the data in our local state

As you can see we explicitly spell out how and what to do at every step in fetching the data. Almost every React developer is familiar with the lines of code above. Though the syntax and functions work correctly, the code can be re-written to be more elegant and in fewer lines, if written declaratively. Let’s rewrite it using React Async.

First, you need to install the package by typing npm install react-async in your terminal. Then write your component with the following code:

import React, { Component } from 'react';
import Async from 'react-async';

const loadJson = () =>
  fetch("https://api.coinmarketcap.com/v1/ticker/?limit=1")
    .then(res => (res.ok ? res : Promise.reject(res)))
    .then(res => res.json())

const App = () => (

    {({ data, error, isLoading }) => {
      if (isLoading) return "Loading..."
      if (error) return ``Something went wrong: ${error.message}``

      if (data)
        return (

             {data.map(el => (

                {el.name}: {el.price_usd}

             ))}

        )

      return null
    }}

)

export default App;

However, since we are using CodeSandbox, we will add React-Async from the dependency menu.

Here we have rewritten our component using hooks instead of classes. We first create a function loadJson to handle our data fetching. Then, inside our App component, we utilize the Async component made available through the React Async library.

Once our promise is resolved, props are made available to us to handle different scenario's.

  • isLoading is available so we can display a user-friendly message while the data is yet to be loaded.
  • error is available in case of an error during the fetch.
  • data is the actual data returned after the fetching is complete.

As we can see, we no longer have to use classes or lifecycle methods to load our data neither did we tell React-Async how to process the data or how to update our state.

React Async manages the loading state through the isLoading fallback prop, which is rendered until data is ready to be rendered, that is when the dependent asynchronous call resolves and returns the data.

Helper Components

React Async comes with several helper components that make your JSX more declarative and less cluttered. Each of the helper components will only render its children when appropriate. We can rewrite our App function to look like this:

const App = () => (

    Loading...


      {data => (

          {data.map(el => (

              {el.name}: {el.price_usd}

          ))}

      )}



      {error => `Something went wrong: ${error.message}`}


)

In the example above, we have utilized the **Async.Loading**, **Async.Resolved** and **Async.Rejected** functions to simplify our code and make it more readable. Helper components provided by React-Async can take a React element or a function as children. When you provide a function, you’ll receive render props you can use in your component.

More Helper Functions

Let’s build a small user profile app that utilizes some more helper functions. Update your component to the following code:

import React, { Component } from 'react';
import Async from 'react-async';

const loadUser = ({ userId }) =>
  fetch('`https://reqres.in/api/users/${userId}'`)
    .then(res => (res.ok ? res : Promise.reject(res)))
    .then(res => res.json())

const UserPlaceholder = () => (

    User Details Loading


)

const UserDetails = ({ data }) => (



      {data.data.first_name} {data.data.last_name}


)

const App = () => (




      {data => }
      {error => 
{error.message}
}

)
export default App;

Let’s go over the functions we declared :

  • loadUser **- We define this function to handle data fetching.** It takes in a prop (userId) and queries the API based on the id.
  • userPlaceholder - This is the fallback component that will be displayed when the promise has not yet resolved. (When the data has not finished loading).
  • *userDetails *- This component handles the actual display of the user data. It takes the data in via props and is only rendered when the promise has been resolved.
  • **Finally,* we utilized the `Async.Pending_,_Async.Fulfilled_and_**Async.Rejected\*` functions to simplify our code and make it more readable.

To learn more check out the docs here

Angular 9 Tutorial: Learn to Build a CRUD Angular App Quickly

What's new in Bootstrap 5 and when Bootstrap 5 release date?

Brave, Chrome, Firefox, Opera or Edge: Which is Better and Faster?

How to Build Progressive Web Apps (PWA) using Angular 9

What is new features in Javascript ES2020 ECMAScript 2020

Hire Dedicated eCommerce Web Developers | Top eCommerce Web Designers

Build your eCommerce project by hiring our expert eCommerce Website developers. Our Dedicated Web Designers develop powerful & robust website in a short span of time.

JavaScript developers should you be using Web Workers?

Do you think JavaScript developers should be making more use of Web Workers to shift execution off of the main thread?

Why ReactJS is better for Web Application Development?

Web Application Development is the point of contact for a business in today's digital era. It is important to choose the right platform for Web Application Development to build a high end Web