Destructuring and abstracting the fetchData in React
Tags: react, productivity, performance
Published: 2022-09-20 20:03:11

# 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](https://github.com/ViniBGoulart/abstracting-fetchData/tree/start), 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c6xjxer3h2kzydes3jfr.png)
Here we have a hook consulting github api.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8hzj4pfkoyqv2xpk6117.png)
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**:
```js
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 };
};
```
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:
```js
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 };
}
```
> src > hooks > useGithub.ts

```js
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 };
}
```
> 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](https://github.com/ViniBGoulart/abstracting-fetchData/)!