React
Posted By Sebastian

Modern React From The Beginning EP10: Handling Of Asynchronous Data


Subscribe On YouTube

Episodes

In the last episodes you’ve already learnt about handling data in your React web application. In a real-world scenario you’ll also need to learn how to deal with data which is coming from outside of your application (e.g. from a web service, data base etc.). This requires us to also learn handling asynchronous data. This episode will introduce you to handling asynchronous data in your React application. At the first attempt we’ll just simulate asynchronous data within our application.

Renaming The Courses Array

First, let’s rename the array which is containing the course sample data from courses to courses_data:

const courses_data = [ ... ]

Adding A State To Courses Component

In the second step we’re making use of State Hook once again to create a new App component state named courses. Therefore insert the following line of code into the App function:

const [courses, setCourses] = useState([]);

This new component state will be used to store the list of courses inside of App component.

Retrieving The Courses Array In An Asynchronous Way

Because this tutorial is about handling asynchronous data in your React applications let’s simulate an asynchronous data source by implementing the following function within App component:

  const getCoursesAsync = () => 
    new Promise(resolve => 
        setTimeout(
          () => resolve({ courses: courses_data }),
          2000
        )
      );

The getCoursesAsync function returns a Promise which gets resolved after two seconds (by using the setTimeout function). When the Promise gets resolved an object is returned containing a courses property which gets assigned the courses_data array.

The function will help us to simulate an asynchronous data source which is delivered our courses data with a delay (e.g. like we would request it from a remote REST endpoint).

Using The Effect Hook To Initialize The Courses State

The getCoursesAsync function will then be used to set the courses state. The courses state needs to be set at the beginning of the component’s lifecycle. As already explained in the last episode we’re able to make use of an Effect Hook (with an empty list of dependant variables) to hook into the component’s lifecycle call the getCoursesAsync function and set the state value once the returned Promise gets resolved:

  useEffect(() => {
    getCoursesAsync().then(result => {
      setCourses(result.courses);
    })
  }, []);

Loading Indicator

When accessing the application in the browser you can already see the effect of the changes made. Once the page is loaded you can only see the headline and the search field. The list of courses is appearing automatically after 2 seconds. To let the user know that data needs to be loaded first, we’re also able to add a loading indicator to the application. To do so add another state (isLoading) to App component and initialize the state with the value false.

const [isLoading, setIsLoading] = useState(false);

Now we’re using this state inside the useEffect call:

  useEffect(() => {
    setIsLoading(true);
    getCoursesAsync().then(result => {
      setCourses(result.courses);
      setIsLoading(false);
    });
  }, []);

Before the getCoursesAsync function is called we’re setting the value to true. After the returned promise is resolved (and the courses data is available) we’re setting it back to false.

Inside the JSX code of App component we’re now ready to introduce conditional rendering based on the isLoading value:

      {isLoading ? (
        <p>Loading Courses ...</p>
      ) : (
        <CoursesList courses={filteredCourses} />
      )}

When the data load is in progress (isLoading is set to true) we’re just printing out the text “Loading Courses …” to let the user know what is going on.

Once the loading is done (isLoading is false) we’re making use of CoursesList component to output the list of courses. The loading message is no longer rendered out.

Finally, you can see the complete source code of App component in the following:

import React, {useState, useEffect} from 'react';
import CoursesList from './CoursesList';
import Search from './Search';

const courses_data = [
  ...
]; 

const App = () => {

  const getCoursesAsync = () => 
    new Promise(resolve => 
        setTimeout(
          () => resolve({ courses: courses_data }),
          2000
        )
      );
  
  const [courses, setCourses] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  const [searchText, setSearchText] = useState(
    localStorage.getItem('searchText') || ''
  );

  const handleSearch = event => {
    setSearchText(event.target.value);
  }

  useEffect(() => {
    localStorage.setItem('searchText', searchText)
  }, [searchText]);

  useEffect(() => {
    setIsLoading(true);
    getCoursesAsync().then(result => {
      setCourses(result.courses);
      setIsLoading(false);
    });
  }, []);

  const filteredCourses = courses.filter(course => {
    return course.title.includes(searchText) || course.author.includes(searchText);
  });

  return (
    <div>
      <h1>List of Courses</h1>
      <hr />

      <Search value={searchText} onSearch={handleSearch} />
      
      {isLoading ? (
        <p>Loading Courses ...</p>
      ) : (
        <CoursesList courses={filteredCourses} />
      )}
      
    </div>
  );
}

export default App;

Advertisement: Top 3 React Online Courses

If you want to dive deeper and become a React pro also consider taking one of the following great online courses.

React – The Complete Guide (incl Hooks, React Router, Redux)*
Dive in and learn React.js from scratch! Learn Reactjs, Hooks, Redux, React Routing, Animations, Next.js and way more!

Go To Course*

Modern React with Redux*
Master React v16.6.3 and Redux with React Router, Webpack, and Create-React-App. Includes Hooks!

Go To Course*

The Complete React Developer Course (w/ Hooks and Redux)*
Learn how to build and launch React web applications using React, Redux, Webpack, React-Router, and more!

Go To Course*

* Affiliate Link / Advertisement: This blog post contains affiliate links, which means that if you click on one of the product links and buy a product, we’ll receive a small commission. There are no additional costs for you. This helps support the channel and allows us to continue to make videos like this. Thank you for the support!


Using and writing about best practices and latest technologies in web design & development is my passion.