DEV Community

Vinicius Blazius Goulart
Vinicius Blazius Goulart

Posted on

Destructuring and abstracting the fetchData in React

What will be done?

We'll learn how destructure and abstract the fetchData in React. It'll make our applications more performative and scalable.

Used technologies

  • React
  • Custom Hooks
  • Yarn

Starting

I'll use a project base to start this post that you might access in my GitHub in this repo abstracting-fetchData, using start branch.
In it there is a react application created in the usual way, with some routes, components and hooks. Clone the project in your computer and install dependencies running yarn.

The project base has two pages that you can navigate through the navbar.

  • The Github page calls the github API and shows some profile data.
  • The Pokemon page calls the pokeapi and shows some pokemonn data.

Commom mode

Everybody know that abstracts component logic into hooks is good to performatic applications, it makes testing easier and more scalable. Most projects use this architecture, components with their logic decoupled in hooks. We can see this here:

Image description
Here we have a hook consulting github api.

Image description
And here we have a hook consulting pokeapi.

You can see that both hooks have a fetch on some URL. Have you ever thought about how you can abstract this and the application go the usual way? Fortunately, react provides this functionality of render the components when other linked component changes. You will understand better soon...

Abstracting fetch Data

Let's abstract the fetchData. Create a new file in src > hooks > useFetch.ts:

import { useEffect, useState } from "react";

export const useFetch = <T>(url: string) => {
  const [response, setResponse] = useState<T>();

  useEffect(() => {
    (async () => {
      try {
        const res = await fetch(url);
        const data = await res.json();

        setResponse(data);
      } catch (err) {
        console.log(err);
      }
    })();
  }, [url]);

  return { response };
};
Enter fullscreen mode Exit fullscreen mode

Here we have a function that accepts a url parameter and does a new fetch when the url changes, setting and returning the data.

Now, our custom hooks will call this hook, passing as param the url:

import { useFetch } from "./useFetch";

interface Github {
  name: string;
  avatar_url: string;
}

export function useGithub() {
  const { response } = useFetch<Github>("https://api.github.com/users/ViniBGoulart");

  return { github: response };
}
Enter fullscreen mode Exit fullscreen mode

src > hooks > useGithub.ts

import { useFetch } from "./useFetch";

interface Pokemon {
  name: string;
  sprites: {
    front_default: string;
  };
}

export function usePokemon() {
  const { response } = useFetch<Pokemon>("https://pokeapi.co/api/v2/pokemon/ditto");

  return { pokemon: response };
}
Enter fullscreen mode Exit fullscreen mode

src > hooks > usePokemon.ts

Is necessary change the page component also, put a optional chaining in objects, like github?.avatar_url.

Voilà! We abstract the useFetch logic, making scaling and testing easier!

You might access final project here abstracting-fetchData!

Top comments (0)