Um aplicativo mobile normalmente possui um banco de dados online e por isso ele não consegue realizar todas as suas funcionalidades sozinho - para isso ele precisa enviar requisições a uma API (back-end).

Aprender a consumir dados de uma API é fundamental para um programador React Native.

Como acessar uma API?

No React Native existem duas formas para consumir dados de uma API que é através de uma biblioteca, por exemplo Axios ou com o método nativo do JavaScript chamado fetch. Neste artigo você vai aprender a consumir uma API através do método fetch.

Uma requisição através do fetch é feita conforme o Código 1.

fetch('https://www.minhaapi.com.br');
Código 1. Requisição através do fetch

O código acima envia uma requisição para a URL passada por parâmetro.

Ao enviar uma requisição esperamos receber dados, para isso precisamos utilizar o método then. Dentro dele inserimos uma função que será executada apenas quando fetch receber um retorno da API.

Veja no Código 2 um exemplo de uso dos métodos fetch e then.

fetch('https://www.meusite.com.br/api')
      .then( (resposta) => resposta.json())
Código 2. Exemplo de uso do fetch e then

No código acima realizamos uma requisição à API e quando ela retornar uma resposta a função dentro de then será executada.

A Figura 1 mostra como o código é executado.

Como o código é executado
Figura 1. Execução do código 2

A função dentro de then, recebe uma resposta e tenta converter para JSON através do método .json(), como mostra o Código 3.

(resposta) => resposta.json()
Código 3. Uso do método .json()

Após executar o método .json() queremos que uma função seja chamada. Para isso utilizaremos mais uma vez o then. Dessa vez, porém caso a tentativa de converter a resposta gere um erro queremos que outra função seja executada. Para isso utilizaremos o método catch.

Veja no Código 4 como isso é feito.

fetch('https://www.meusite.com.br/api')
      .then( (resposta) => resposta.json())
          .then( ( json ) => console.log(json) )
          .catch( ( error ) => console.error(error) )
  
Código 4. Executando uma função depois de tentar converter a resposta em JSON

Entenda o código acima:

Linha 1: Enviamos uma requisição através do método fetch para a URL passada por parâmetro.

Linha 2: Somente depois que a requisição receber uma resposta, a função dentro de then será executada. Essa função por sua vez recebe a resposta da API e tenta convertê-la para JSON.

Linha 3: Caso o método .json() execute sem gerar erro, a função dentro de then será executada.

Linha 4: Caso o método .json() gere um erro, a função dentro do método catch será executada.

Veja na Figura 2 a representação da execução do código.

Como o código é executado
Figura 2. Fluxo de execução do código ao tentar converter a resposta para JSON

Parâmetros opcionais para enviar uma requisição

Ao enviar uma requisição para uma API é possível personalizar a requisição enviada como por exemplo alterar o método de envio ou enviar parâmetros no corpo da requisição.

Para personalizar a requisição passamos um segundo parâmetro (um objeto) para o método fetch como pode ser visto no Código 5.

fetch('https://www.meusite.com.br/api', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      nome: 'José',
      idade: 28
    })
  });
  
Código 5. Personalizando a requisição

Vamos analisar as propriedades do objeto que passamos como segundo parâmetro para fetch.

Linha 2: A propriedade method recebe o verbo HTTP. Exemplos: POST, GET, PUT, PATCH, DELETE).

Linha 3: A propriedade headers recebe o cabeçalho da requisição. Nesse caso estamos dizendo que estamos enviando um JSON na requisição.

Linha 7: Dentro da propriedade body passamos o corpo da requisição. É aqui que passamos os parâmetros que serão enviados para a API sem que eles sejam exibidos na URL.

A Figura 3 reforça o que aprendemos.

Como o código é executado
Figura 3. Representação visual da requisição

Veja como ficaria uma requisição personalizada no Código 6.

fetch('https://www.meusite.com.br/api', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      nome: 'José',
      idade: 28
    })
  })
    .then(resposta => resposta.json())
      .then( (json) => console.log(json))
      .catch((error) => console.error(error));
  
Código 6. Exemplo completo de uma requisição personalizada

Exemplo de requisição a uma API

Veja um exemplo de um aplicativo simples que possui uma lista com três Pokémons. Cada Pokémon possui um botão que ao ser clicado vai chamar uma API para exibir o nome em inglês, o peso e a foto do Pokémon como exibe a Animação 1.

Como o código é executado
Animação 1. Aplicativo em execução

Veja aqui a documentação da API que foi utilizada nesse exemplo.

Veja no Código 7 o componente.

  import React, { useState } from 'react';
  import { Alert, View, ScrollView, Text, Image, Button, StyleSheet, } from 'react-native';
  const pokemonsIniciais = [
    { id: 1, nome: "Bulbasauro"},
    { id: 4, nome: "Charmander"},
    { id: 7, nome: "Squirtle"},
  ];
   
  export default function App() {
    const [ pokemonEscolhido, setPokemonEscolhido ] = useState(null);
    
    const getPokemonData = (idPokemon) => {
      const endpoint = `https://pokeapi.co/api/v2/pokemon/${idPokemon}/`;
   
      fetch(endpoint)
        .then(resposta => resposta.json())
          .then( json => {
            const pokemon = {
              nome: json.name,
              img: json.sprites.other["official-artwork"].front_default,
              peso: json.weight,
            };
   
            setPokemonEscolhido(pokemon);
          })
          .catch(() => {
            Alert.alert('Erro', 'Não foi possível carregar os dados do Pokémon');
          });
    }
   
    return (
      <View style={styles.container}>
        <ScrollView>
          <View style={styles.topo}>
            <Text style={styles.topoTitulo}>ESCOLHA SEU POKÉMON</Text>
          </View>
   
          {pokemonEscolhido != null && (
            <View style={styles.pokemonBox}>
              <Text style={styles.pokemonNome}>Nome: {pokemonEscolhido.nome}</Text>
              <Text style={styles.pokemonPeso}>Peso: {pokemonEscolhido.peso}</Text>
              
              <Image resizeMode="stretch" source={{uri:pokemonEscolhido.img}} style={styles.pokemonImg} />
            </View>
          )}
   
          {pokemonsIniciais.map( pokemon => (
            <View style={styles.cardContainer}>
              <Text style={styles.cardTitle}>{pokemon.nome}</Text>
              <Button title="Dados do pokémon" onPress={()=>getPokemonData(pokemon.id)}/>
            </View>
          ))}
        </ScrollView>
      </View>
    );
  }
   
  const styles = StyleSheet.create({
    container: { flex: 1, backgroundColor: '#fff' },
    
    topo: { height: 80, padding: 20, paddingTop: 40, marginBottom: 20, backgroundColor: '#e73e33' },
    topoTitulo: { fontSize: 22, marginBottom: 10, color: '#fff', textAlign: 'center'},
    
    cardContainer: { borderWidth: 1, borderColor: '#d5d5d5', borderRadius: 4, marginBottom: 10, marginHorizontal: 20, padding: 10 },
    cardTitle: { fontSize: 22, marginBottom: 20, textAlign: 'center', color: '#656565' },

    pokemonBox: { alignItems: 'center' },
    pokemonNome: { fontSize: 22 },
    pokemonPeso: { fontSize: 18 },  
    pokemonImg:{ width: 150, height: 150,}
  });
Código 7. Código do componente que acessa uma API

Acima temos um código comum em React Native que você já está familiarizado, por isso vamos entender apenas os pontos que representam o conteúdo deste artigo que é o consumo da API.

Entenda o código acima no flow seguinte:

flow flow flow flow flow flow flow flow flow flow

Conclusão

Neste artigo aprendemos a consumir uma API em React Native através do método fetch nativo do JavaScript. Ao aprender este conceito você deu mais um passo na sua carreira de programador React Native.