Wednesday, February 23, 2022

Using Async Await Inside React’s useEffect() Hook

You'll learn how to use an async function in your React useEffect hook in this article. Perhaps you've been utilizing a.then() method chain using the previous Promise syntax. Let's study how to integrate async/await functions with React's useEffect hook using a Promise-based refactoring, as we may easily make a mistake and give ourselves some headaches if we don't know a few essential elements.


Assuming the following example, we're using a useState hook to establish some initial state as [], which we'll want to populate with a GET request when the component mounts.


We let a useEffect hook spin-off a fast fetchUsers() call once the component mounts, which gets us a Promise type, which we evaluate via. then() and use the setUsers() setter function to populate our users value.


const Users = () => {

  const [users, setUsers] = useState([]);


  useEffect(() => {

    fetchUsers().then((users) => setUsers(users));

  }, []);


  if (!users) return <div>Loading...</div>;


  return (

    <ul>

      {users.map((user) => (

        <li>{user.name}</li>

      ))}

    </ul>

  );

};




With that in mind, shouldn't we introduce async as a function and pair it with an await statement? Not so fast, my friend. That technique appears to work on the surface, but there are several hidden trapdoors that we could fall into if we go refactoring blindly - hence the writing of this blog article.


// ❌ Don't do this!

useEffect(async () => {

  const users = await fetchUsers();

  setUsers(users);


  return () => {

    // this never gets called, hello memory leaks...

  };

}, []);


This WORKS, but it's something you should avoid. Why? Because the useEffect hook in React wants a cleaning function to be returned from it after the component unmounts. If you use an async function here, the cleanup function will never be invoked, resulting in a problem. Oops! So, what are our options?


To put it another way, under the useEffect hook, we should use an async function. An immediately-invoked function expression or a named function that you activate are the two patterns you can utilise. Let's compare and contrast so you can determine which is your favourite.


// 🆗 Ship it

useEffect(() => {

  (async () => {

    const users = await fetchUsers();

    setUsers(users);

  })();


  return () => {

    // this now gets called when the component unmounts

  };

}, []);


Alternatively, you can use a named function:


// 🆗 Ship it

useEffect(() => {

  const getUsers = async () => {

    const users = await fetchUsers();

    setUsers(users);

  };


  getUsers(); // run it, run it


  return () => {

    // this now gets called when the component unmounts

  };

}, []);


In any case, using async functions inside useEffect hooks is now safe. Now, if/when you want to return a cleanup function, it will be called, and useEffect will be kept clean and free of race situations.


From now on, enjoy using async functions with React's useEffect!

 

 

No comments:

Post a Comment

Overview of JavaScript training in Bangalore

  JavaScript is an interpreted scripting language that helps to add dynamic and interactive elements to the website. It is used for front-en...