Skip to content

Latest commit

 

History

History
77 lines (55 loc) · 2.44 KB

File metadata and controls

77 lines (55 loc) · 2.44 KB

In this lesson, we will learn how to run asynchronous code using the useEffect hook. By asynchronous code, I mean synchronizing the data to a backend or sending any network requests.

Action: Switch to TaskApp.tsx

We don't have any backend yet, instead we will print a message to the console using a setTimeout. Let's open the TaskApp.tsx file in Visual Studio Code.

Let's import useEffect hook first.

import React, { useEffect } from "react";

You can also instead use the hook from an already imported React package as React.useEffect.

Let's now remove the line that updates the title when each task is added.

Action: Remove document.title = line from TaskApp.tsx

React.useEffect(() => {}, [taskAppState.tasks]);

We can now mock sending a network request by using a setTimeout.

Action: Add the following code right after declaring the state hooks.

React.useEffect(() => {
  const id = setTimeout(() => {
    console.log(`Saved ${taskAppState.tasks.length} items to backend...`);
  }, 5000);
  return () => {
    console.log("clear or cancel any existing network call");
    clearTimeout(id);
  };
}, [taskAppState.tasks]);

With this code in place, the useEffect will schedule a function, which will be invoked after 5 seconds, after a new task is added.

Let's save the file. We can now switch to our browser, and open the developer tools.

Action: switch to browser and open the developer console. Add few tasks using the UI.

Now, let's try adding a few tasks.

As you can see, the setTimeout gets invoked correctly. Whenever a new task is added, the previously scheduled setTimeout is cleared and is not invoked. You can easily verify it by commenting out the clearTimeout.

While writing async code in useEffect hook, it is easy to get async-await usage wrong. Do not mark the callback function as async and directly use await in the body.

React.useEffect(async () => {
  // This is wrong usage
  const token = await saveTasksToBackend(taskAppState.tasks);

  return () => {
    cancelAPI(token);
  };
}, [taskAppState.tasks]);

In such a code, the clean-up function will never get executed. Instead, we can write

React.useEffect(() => {
  // This is correct usage
  const saveTasks = async () => {
    const token = await saveTasksToBackend(taskAppState.tasks);
  };
  saveTasks();
  return () => {
    cancelAPI(token);
  };
}, [taskAppState.tasks]);

See you in the next lesson.