React - API, por que te adoro?
Published: 2021-02-19 15:48:17

##:wave: Introdução

Nos últimos posts vimos pra que serve React, como criar um projeto e como estilizá-lo. Porém agora temos que consumir os dados de um back-end.

Para testarmos, utilizaremos uma API fake e para isso uma pacote chamado [json-server](https://github.com/typicode/json-server).

##:factory: Iniciando nossa API

Primeiro vamos instalar essa pacote globalmente:

```bash
npm install -g json-server
```

Após isso vamos criar um arquivo `db.json` na raiz do nosso projeto:

```json
{
  "transactions": [
    {
      "id": "1",
      "category": { "title": "Venda" },
      "title": "Desenvolvimento de site",
      "type": "income",
      "value": 12000,
      "created_at": "2020-04-13T00:00:00"
    },
    {
      "id": "2",
      "category": { "title": "Alimentação" },
      "title": "Hamburger",
      "type": "outcome",
      "value": 59,
      "created_at": "2020-04-10T00:00:00"
    },
    {
      "id": "3",
      "category": { "title": "Casa" },
      "title": "Aluguel do apartamento",
      "type": "outcome",
      "value": 1200,
      "created_at": "2020-03-27T00:00:00"
    },
    {
      "id": "4",
      "category": { "title": "Venda" },
      "title": "Computador",
      "type": "income",
      "value": 5400,
      "created_at": "2020-03-15T00:00:00"
    }
  ]
}
```

E agora para rodar a API, abra um novo terminal e rode:

```bash
json-server --watch db.json --port 3333
```

http://localhost:3333/transactions para acessar os itens do JSON. Deixe esse terminal aberto e rodando para que a API não caia.

O que temos que fazer agora é consumir essa API no nosso front-end.

##:satellite: Consumindo API

Existem várias bibliotecas para isso, porém utilizaremos o [axios](https://github.com/axios/axios). E para instalar:

```bash
npm install axios
```

Já que vamos sempre consumir de uma mesma API nossas informações vamos criar primeiro uma base no arquivo `src/services/api.ts`:

```typescript
// services/api.ts

import axios from 'axios';

const api = axios.create({
  baseURL: 'http://localhost:3333',
});

export default api;
```
Assim, sempre que precisarmos consumir nossa API, vamos importar essa service e utilizá-la.

Vamos no arquivo `pages/Home/index.tsx` e limpar os `useState` para eles ficarem em branco.

```react
// pages/Home/index.tsx

const [balance, setBalance] = useState<Balance>({
    income: 0,
    outcome: 0,
    total: 0,
  });

  const [transactions, setTransactions] = useState<Transaction[]>([]);
```

O que queremos é:
- Ao abrir a tela, os dados da API devem ser pegados e mostrados em tela.
- Ao mesmo tempo, é calculado o balanço e depois alterado o valor dos Cards.

Sempre que o React tem um dos seus estados alterados todo o componente é recarregado, e por isso não podemos escrever código diretamente dentro da função **Home**. Para isso, o React nos fornece um hook `useEffect` que executa um trecho de código sempre que algum das suas dependências forem alteradas; se não houver dependências ele só é executado na primeira vez que código é carregado.
Pareceu confuso? Na prática é bem simples.

O `useEffect` é uma função que recebe dois parametros:
- Uma função a ser executada.
- Um array com suas dependencias

```react
// pages/Home/index.tsx

import { useEffect, useState } from "react";

// adicionar abaixo dos useState

useEffect(() => {
    setBalance({
      income: 10,
      outcome: 0,
      total: 10,
    });
  }, []);
```

O que fizemos aqui foi que na primeira vez que o componente **Home** for renderizado ele irá 'setar' a variável balance com um novo valor.

Vamos utilizar o `useEffect` para buscar nossa API:

```react
// pages/Home/index.tsx

import { useEffect, useState } from "react";

// adicionar abaixo dos useState

useEffect(() => {
    setBalance({
      income: 10,
      outcome: 0,
      total: 10,
    });
  }, []);
```
Explicando um pouco de como funciona o axios:

- Primeiro importamos o nosso service.
- Depois utilizamos ele informando qual método HTTP iremos utilizar. Como vamos 'pegar' uma lista de dados, utilizamos `get`.
- Passamos `<Transaction[]>` para informar ao Axios qual a tipagem dos dados que a API retornará.
- Passamos 'transactions' como sendo nossa rota, assim o axios fará uma requisição para http://localhost:3333/transactions.
- Como essa busca leva uma tempo, temos que utilizar o `.then`. Isso é a parte assíncrona do Javascript, onde se não utilizarmos o `then` o Javascript não esperaria a resposta da API para proseguir.
- O `then` recebe como parâmetro uma função de callback, onde o argumento dessa função é toda resposta da API.
- Estamos desestruturando essa resposta para pegarmos apenas os dados (data).
- Por fim estamos 'setando' a nossa lista de transações para ser os dados enviados pela API.

Ufa... Em três linhas de código muito aconteceu. Mas isso é o básico de como consumir uma API.

Caso não tenha entendido, ou queira se aprofundar mais no axios tem um [post](https://blog.rocketseat.com.br/axios-um-cliente-http-full-stack/) bem legal no blog da Rocketseat sobre o axios. Aconselho a darem uma olhada se quiserem.

##:balance_scale: Atualizando o balanço

Para isso também vamos utilizar outro useEffect só que agora esse terá uma dependencia, que será a lista de transações (transactions). Se liga só:

```react
// pages/Home/index.tsx

import { useEffect, useState } from "react";

import Header from "../../components/Header";

import Cards, { Balance } from "../../components/Cards";
import TransactionList, { Transaction } from "../../components/TransactionList";

import { Container } from "./styles";

import api from "../../services/api";

function Home() {
  const [balance, setBalance] = useState<Balance>({
    income: 0,
    outcome: 0,
    total: 0,
  });

  const [transactions, setTransactions] = useState<Transaction[]>([]);

  // AQUI
  useEffect(() => {
    const newBalance: Balance = transactions.reduce(
      (acc, val) => {
        acc[val.type] += val.value;

        return acc;
      },
      { income: 0, outcome: 0, total: 0 }
    );

    newBalance.total = newBalance.income - newBalance.outcome;

    setBalance(newBalance);
  }, [transactions]);

  useEffect(() => {
    api.get<Transaction[]>("transactions").then(({ data }) => {
      setTransactions(data);
    });
  }, []);

  return (
    <>
      <Header />
      <Container>
        <Cards balance={balance} />
        <TransactionList transactions={transactions} />
      </Container>
    </>
  );
}

export default Home;
```

Estamos utilizando um reduce para percorrer todos os item da lista e retornar o somatório entre cada tipo de transação.
Depois calculamos o total, e por fim 'setamos' o `balance` como sendo o `newBalance`.

##:disappointed_relieved: É o fim?

Com isso terminamos nossa primeira tela no React. É algo simples e pratico que eu espero que tenha te mostrado o quão bom o React pode ser.

Mas isso não quer dizer que chegamos ao fim. Ainda falta muita coisa para aprendermos, estamos apenas arranhado a superfície.

No próximo post vamos criar uma nova tela e descobrir como trocar entre rotas da aplicação.

PS: Um agradecimento especial:purple_heart: ao pessoal da [Rocketseat](https://rocketseat.com.br/):rocket: pelo conteúdo de qualidade em React.