DEV Community

Alexandru-Dan Pop
Alexandru-Dan Pop

Posted on Edited on Originally published at alexandrudanpop.dev

Correctly handling async/await in React components - Part 2

Correctly handling async/await in React components - Part 1

The refactored

In the first post we cancelled requests and ignored stale results. Now let's move that logic into a custom hook. Our component only needs to display the joke. ⭐

The example expects your own /api/joke endpoint to return { "joke": "..." }.

import React, { useState, useEffect } from "react";
import axios from "axios";

const useJokeAsync = (more) => {
  const [joke, setJoke] = useState("");

  useEffect(() => {
    const controller = new AbortController();
    let active = true;

    async function fetchJoke() {
      try {
        const response = await axios("/api/joke", {
          signal: controller.signal,
        });
        if (active) setJoke(response.data.joke);
      } catch (err) {
        if (active && !axios.isCancel(err)) console.error(err);
      }
    }

    fetchJoke();
    return () => {
      active = false;
      controller.abort();
    };
  }, [more]);

  return joke;
};

export default function RandomJoke({ more, loadMore }) {
  const joke = useJokeAsync(more);

  return (
    <div>
      <h1>Here's a random joke for you</h1>
      <h2>{joke}</h2>
      <button onClick={loadMore}>More...</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Aborting stops a supported request. The active flag separately prevents an old effect from updating state. We keep both inside the hook.

Conclusions

Custom hooks help isolate concerns like data fetching and keep components easy to read. No separate mounted-ref hook needed. ✅

Top comments (2)

Collapse
 
navicsteinr profile image
Navicstein Rotciv •

Well done, ive been struggling how to appropriately handle async storage because the Ajax request will already send the nulled token before the DB is resolved, but this saved my day, thanks 💪

Collapse
 
alexandrudanpop profile image
Alexandru-Dan Pop • • Edited

Glad I could be of help, mate!