Conectando com APIs Backend

Área: Frontend | Nível recomendado: Iniciante

Esta missão ensina como as aplicações React interagem com APIs backend. Aprenderemos a usar a Fetch API para fazer requisições HTTP, gerenciar o estado e os efeitos colaterais com hooks do React, e construir um componente interativo que consome uma API, processando respostas e lidando com erros de forma eficaz.

Vídeo

Link direto: https://youtu.be/hTncMAFn0ns

Tópicos

  1. Introdução às APIs e Uso da Fetch API:

    • Discussão sobre o papel das APIs na comunicação entre frontend e backend.

    • Como usar a Fetch API para realizar requisições GET e POST para um servidor backend.

  2. Hooks para Gerenciamento de Estado e Efeitos:

    • Detalhes sobre como utilizar os hooks useState e useEffect para gerenciar o estado e lidar com efeitos colaterais em React.

    • Exemplos práticos de como esses hooks são essenciais para interações dinâmicas com APIs.

  3. Manipulação de Respostas e Tratamento de Erros:

    • Técnicas para manipular respostas de API e realizar tratamento adequado de erros.

    • Estratégias para garantir que a aplicação se comporte de maneira robusta em cenários de erro.

  4. Construção de um Componente Interativo:

    • Implementação de um componente que faz requisições a uma API e exibe dados.

    • Inclusão de funcionalidades interativas, permitindo aos usuários enviar dados para o backend e receber respostas que alteram a UI.

Material de Apoio

Repositório no GitHub

PDF para Download

Miro

Exercícios de Fixação

Use esses exercícios para reforçar o que acabou de aprender. Se errar, leia a explicação para entender melhor o conceito.

Qual é a função principal da Fetch API no desenvolvimento web?

A) Instalar pacotes npm automaticamente.

B) Facilitar a comunicação entre o frontend e o backend através de requisições HTTP.

C) Criar componentes React.

D) Inicializar um novo projeto NodeJS.

Resposta correta

Qual é a função principal da Fetch API no desenvolvimento web?

Resposta Correta: B

Feedback: A Fetch API facilita a comunicação entre o frontend e o backend através de requisições HTTP, permitindo que os dados sejam enviados e recebidos de um servidor.


Complete o código para realizar uma requisição GET usando a Fetch API.
async function fetchData() {
  try {
    const response = await fetch('https://api.exemplo.com/data');
    const data = await response.________();
    console.log(data);
  } catch (error) {
    console.error('Erro:', error);
  }
}

fetchData();
Resposta correta

Complete o código para realizar uma requisição GET usando a Fetch API.

Resposta Correta: json

Feedback: O método response.json() é usado para converter a resposta da Fetch API em um objeto JavaScript.


Verdadeiro ou Falso: O hook useState do React é utilizado para gerenciar efeitos colaterais.

A) Verdadeiro

B) Falso

Resposta correta

Verdadeiro ou Falso: O hook useState do React é utilizado para gerenciar efeitos colaterais.

Resposta Correta: B

Feedback: Falso. O hook useState é usado para gerenciar o estado dos componentes React, enquanto o hook useEffect é usado para gerenciar efeitos colaterais.


Complete o código para configurar um endpoint que responde com uma lista de personagens.
export const Api = {
  baseUrl: 'https://backend-iniciante-integrar-com-frontend.onrender.com/',

  personagem: {
    endpoint: function () {
      return Api.baseUrl + 'personagem'
    },
    readAll: function () {
      return this.endpoint() + '/'
    }
  },

  buildApiGetRequest: function (url) {
    return _________(url, { method: 'GET' }).catch(function (error) {
      console.error('Erro ao carregar dados: ' + url, error)
      toast.error('Erro ao carregar dados.')
    })
  }
}
Resposta correta

Complete o código para configurar um endpoint que responde com uma lista de personagens.

Resposta Correta: fetch

Feedback: O método fetch da biblioteca fetch é usado para realizar uma requisição.

Exercícios de Validação

Esses exercícios testarão sua compreensão prática. Revise o feedback para melhorar suas habilidades.

Desafio de Código

Crie um componente React que busque dados de uma API e exiba uma lista de personagens. O componente deve:

  1. Utilizar a Fetch API para buscar dados.

  2. Gerenciar o estado dos dados usando useState.

  3. Utilizar useEffect para realizar a busca de dados quando o componente for montado.

  4. Exibir os dados na interface do usuário.

Resposta esperada
import React, { useState, useEffect } from 'react';
import { Api } from './api';

export default function Personagens() {
  const [personagens, setPersonagens] = useState([]);

  useEffect(function () {
    async function fetchData() {
      try {
        const response = await Api.buildApiGetRequest(Api.personagem.readAll());
        const data = await response.json();
        setPersonagens(data);
      } catch (error) {
        console.error('Erro ao buscar dados:', error);
      }
    }

    fetchData();
  }, []);

  return (
    <div>
      <h1>Lista de Personagens</h1>
      <ul>
        {personagens.map(function (personagem) {
          return <li key={personagem._id}>{personagem.nome}</li>;
        })}
      </ul>
    </div>
  );
}

Feedback: Certifique-se de que o componente está utilizando useState para gerenciar o estado dos personagens e useEffect para buscar os dados da API quando o componente for montado. A lista de personagens deve ser exibida na interface do usuário.

Revisão de Código

import React, { useState, useEffect } from 'react';
import { Api } from './api';

export default function Personagens() {
  const [personagens, setPersonagens] = useState([]);

  useEffect(function () {
    async function fetchData() {
      try {
        const response = await Api.buildApiGetRequest(Api.personagem.readAll());
        const data = await response.json();
        setPersonagens(data);
      } catch (error) {
        console.error('Erro ao buscar dados:', error);
      }
    }

    fetchData();
  }, [personagens]);

  return (
    <div>
      <h1>Lista de Personagens</h1>
      <ul>
        {personagens.map(function (personagem) {
          return <li key={personagem._id}>{personagem.nome}</li>;
        })}
      </ul>
    </div>
  );
}
Resposta Correta

Erro: O array de dependências no useEffect está incorreto. Deve ser um array vazio para que a busca de dados ocorra apenas uma vez quando o componente for montado.

useEffect(function () {
  async function fetchData() {
    try {
      const response = await Api.buildApiGetRequest(Api.personagem.readAll());
      const data = await response.json();
      setPersonagens(data);
    } catch (error) {
      console.error('Erro ao buscar dados:', error);
    }
  }

  fetchData();
}, []); // Correção: array de dependências vazio

Feedback: Certifique-se de que o array de dependências do useEffect está correto para evitar chamadas infinitas à API.

Projeto Prático

Crie uma aplicação React que inclua:

  1. Um componente que busque dados de uma API e exiba uma lista de itens.

  2. Funcionalidade para deletar itens da lista através de uma requisição DELETE.

  3. Tratamento de erros e exibição de mensagens de erro usando react-toastify.

Tarefas

  1. Configuração Inicial:

    • Inicialize um novo projeto React.

    • Instale as dependências necessárias, incluindo react-toastify.

  2. Implementação dos Endpoints no api.js:

    • Implemente funções para realizar requisições GET e DELETE.

  3. Criação do Componente React:

    • Crie um componente que faça uso das funções do api.js para buscar e deletar itens da lista.

    • Utilize react-toastify para tratar e exibir erros.

Código esperado
api.js
export const Api = {
  baseUrl: 'https://backend-iniciante-integrar-com-frontend.onrender.com/',

  personagem: {
    endpoint: function () {
      return Api.baseUrl + 'personagem'
    },
    readAll: async function () {
      try {
        const response = await fetch(this.endpoint(), { method: 'GET' });
        return await response.json();
      } catch (error) {
        console.error('Erro ao carregar dados: ' + this.endpoint(), error);
        throw error;
      }
    },
    delete: async function (id) {
      try {
        const response = await fetch(this.endpoint() + '/' + id, { method: 'DELETE' });
        if (!response.ok) {
          throw new Error('Erro ao deletar item');
        }
      } catch (error) {
        console.error('Erro ao deletar dados: ' + this.endpoint() + '/' + id, error);
        throw error;
      }
    }
  }
};
App.jsx
import React, { useState, useEffect } from 'react';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { Api } from './api';

export default function App() {
  const [items, setItems] = useState([]);

  useEffect(function () {
    async function fetchData() {
      try {
        const data = await Api.personagem.readAll();
        setItems(data);
      } catch (error) {
        toast.error('Erro ao buscar dados');
        console.error('Erro ao buscar dados:', error);
      }
    }

    fetchData();
  }, []);

  const deleteItem = async function (id) {
    try {
      await Api.personagem.delete(id);
      setItems(items.filter(item => item._id !== id));
    } catch (error) {
      toast.error('Erro ao deletar item');
      console.error('Erro ao deletar item:', error);
    }
  };

  return (
    <div>
      <h1>Lista de Itens</h1>
      <ul>
        {items.map(function (item) {
          return (
            <li key={item._id}>
              {item.nome}
              <button onClick={function () { deleteItem(item._id); }}>Deletar</button>
            </li>
          );
        })}
      </ul>
      <ToastContainer />
    </div>
  );
}

Feedback Detalhado

  • Verificação dos Endpoints: Certifique-se de testar cada rota (GET para buscar itens e DELETE para deletar itens) e verificar as respostas.

  • Tratamento de Erros: Utilize o toast.error para exibir mensagens de erro em caso de falhas nas requisições.

  • Estrutura: A aplicação deve utilizar useState para gerenciar o estado dos itens e useEffect para buscar dados da API quando o componente for montado.

Last updated