Gerenciando estado remoto com React Query

oieduardorabelo

Eduardo Rabelo

Posted on May 5, 2021

Gerenciando estado remoto com React Query

React é uma das bibliotecas de front-end mais apreciadas pela comunidade de desenvolvedores. Junto com o React, os termos como DOM Virtual, Componentes Funcionais, Gestão de Estado e Componentes de Ordem-Superior (Higher-Order Components). Entre esses termos, a Gestão de Estado desempenha um papel vital.

O gerenciamento de estado é um dos principais fatores que precisam ser considerados antes de iniciar um projeto React. Os desenvolvedores usam padrões e bibliotecas famosas como Flux, Redux e Mobx para gerenciar o estado em React. No entanto, eles adicionam complexidade e código boilerplate ao seus aplicativos.

Neste artigo, vamos discutir como o React Query aborda o problema mencionado acima, criando um pequeno aplicativo pokemon e mergulhando em seus conceitos-chave.


Dica: Compartilhe seus componentes reutilizáveis entre projetos usando Bit (veja no GitHub). O Bit simplifica o compartilhamento, a documentação e a organização de componentes independentes de qualquer projeto.

Podemos usá-lo para maximizar a reutilização de código, colaboração em componentes independentes e criar aplicativos escaláveis.

O Bit suporta Node, TypeScript, React, Vue, Angular e muito mais.

Exemplo: Explorando componentes reutilizáveis em React ​​compartilhados no Bit.dev


O que é React Query?

React Query é uma das ferramentas de gerenciamento de estado que tem uma abordagem diferente do Flux, Redux e Mobx. Ele apresenta os principais conceitos de Estado-do-Cliente e Estado-do-Servidor. Isso torna o React Query uma das melhores bibliotecas para gerenciar estado, já que todos os outros padrões de gerenciamento de estado tratam apenas do estado do cliente e acham difícil lidar com o estado do servidor que precisa ser buscado, ouvido ou inscrito.

Além de lidar com o estado do servidor, ele funciona incrivelmente bem, sem precisar de configurações customizadas, e pode ser personalizado de acordo com o seu gosto conforme o crescimento do seu aplicativo.

Vamos ver isso na prática usando alguns exemplos.

Instalando o React Query

Em primeiro lugar, vamos instalar a React QUery dentro de um projeto React:

npm install react-query react-query-devtools axios --save
Enter fullscreen mode Exit fullscreen mode

Ou:

yarn add react-query react-query-devtools axios
Enter fullscreen mode Exit fullscreen mode

Configurando Ferramentas de Desenvolvimento

O React Query também tem suas próprias ferramentas de desenvolvimento, que nos ajudam a visualizar o funcionamento interno do React Query. Vamos configurar as ferramentas de desenvolvimento do React Query no arquivo App.js:

import { ReactQueryDevtools } from "react-query-devtools";
function App() {
  return (
    <>
      {/* Os outros componentes da nossa aplicação */}
      <ReactQueryDevtools initialIsOpen={false} />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Quando configuramos as ferramentas de desenvolvimento do React Query, você pode ver o logotipo do React Query na parte inferior esquerda do seu aplicativo, assim:

Ícone React Query Devtools na parte inferior esquerda

React Query Devtools

O devtools nos ajuda a ver como o fluxo de dados acontece dentro do aplicativo, assim como Redux Devtools. Isso realmente ajuda a reduzir o tempo de depuração do aplicativo.

Assim como o GraphQL, o React Query também se baseia em conceitos básicos semelhantes, como

  • Query
  • Mutações
  • Invalidação de Query

Buscando Pokémons usando Query

Neste exemplo, vamos usar a PokéApi. Começaremos com useQuery, que recebe uma chave única e uma função responsável por buscar dados:

import React from "react";
import axios from "axios";
import { useQuery } from "react-query";
import Card from "./Card";
const fetchPokemons = async () => {
 const { data } = await axios.get("https://pokeapi.co/api/v2/pokemon/?limit=50");
 return data;
};
function Main() {
const { data, status } = useQuery("pokemons", fetchPokemons);
const PokemonCard = (pokemons) => {
 return pokemons.results.map((pokemon) => {
  return <Card key={pokemon.name} name={pokemon.name}></Card>;
 });
};
return (
  <div>
  {status === "loading" && <div>Loading...</div>}
  {status === "error" && <div>Error fetching pokemons</div>}
  {status === "success" && <div>{PokemonCard(data)}</div>}
 </div>
);
}
export default Main;
Enter fullscreen mode Exit fullscreen mode

O código acima irá renderizar uma UI como abaixo:

Dados renderizados ao buscar pokemons da pokeapi por meio do react query

Cache no React Query

Como você pode ver, useQuery retorna os dados e o status que podem ser usados ​​para exibir componentes de "Carregando...", mensagens de erro e os dados reais. Por padrão, React Query só solicitará dados quando eles estiverem desatualizados ou antigos.

O React Query armazena os dados em cache para não renderizar os componentes, a menos que haja uma alteração. Também podemos usar alguma configuração especial com useQuery para atualizar os dados em segundo plano.

const {data, status} = useQuery ("pokemons", fetchPokemons, {staleTime: 5000, cacheTime: 10});
Enter fullscreen mode Exit fullscreen mode

A configuração acima fará com que o React Query busque dados a cada 5 segundos em segundo plano. Também podemos definir um cacheTime e um retryTime que define o tempo que o navegador deve manter o cache e o número de tentativas em que ele deve buscar dados.

Redefinindo o Cache com Invalidação de Query

O React Query buscará dados assim que os dados / cache estiverem desatualizados. Isso acontece quando o staleTime padrão é passado. Você também pode invalidar o cache de maneira programática para que o React Query atualize os dados.

Para fazer isso, use queryCache. É uma instância utilitária que contém muitas funções que podem ser usadas para manipular ainda mais as Query e invalidar o cache.

queryCache.invalidateQueries("pokemons");
Enter fullscreen mode Exit fullscreen mode

Variáveis no React Query

Também podemos passar variáveis ​​para a query. Para isso, precisamos transmiti-los como um array.

const { data, status } = useQuery(["pokemons",75], fetchPokemons);
Enter fullscreen mode Exit fullscreen mode

O primeiro elemento será a chave e o resto dos elementos são variáveis. Para usar a variável, vamos fazer algumas modificações em nossa função fetchPokemons.

const fetchPokemons = async (key,limit) => {
 const { data } = await axios.get(`https://pokeapi.co/api/v2/pokemon/?limit=${limit}`);
 return data;
};
Enter fullscreen mode Exit fullscreen mode

Brincando com Mutações

As mutações são normalmente usadas para criar / atualizar / excluir dados ou executar efeitos colaterais do lado do servidor. O React Query fornece o hook useMutation para realizar mutações. Vamos criar uma mutação para criar um pokémon:

import React from "react";
import { useQuery } from "react-query";

function Pokemon() {
  const [name, setName] = useState("");
  const [mutateCreate, { error, reset }] = useMutation(
    (text) => axios.post("/api/data", { text }),
    {
      onSuccess: () => {
        setName("");
      },
    }
  );
  return (
    <div>
      <form
        onSubmit={(e) => {
          e.preventDefault();
          mutateCreate(name);
        }}
      >
        {error && <h5 onClick={() => reset()}>{error}</h5>}
        <input
          type="text"
          value={name}
          onChange={(e) => setName(e.target.value)}
        />
        <br />
        <button type="submit">Create Pokemon</button>
      </form>
    </div>
  );
}

export default Pokemon;
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, quando adicionamos um novo nome de Pokémon e clicamos no botão Criar Pokémon , ele fará a mutação e irá buscar os dados. Se a mutação falhar, o erro será exibido.

O erro e o estado dos dados podem ser eliminados usando a função reset, que reinicializará a mutação. A função onSuccess pode ser usada para limpar o estado da entrada ou do nome.

Uma mutação tem mais propriedades como onSuccess, isIdle , isLoading , isError , isSuccess. Eles podem ser usados ​​para lidar com erros e exibir informações relevantes para diferentes estados da mutação.

Conclusão

O React Query é uma das melhores maneiras de buscar, armazenar em cache e atualizar dados remotos. Precisamos apenas dizer à biblioteca onde você precisa buscar os dados, e ela tratará do cache, das atualizações em segundo plano e da atualização dos dados sem nenhum código ou configuração extra.

Ele também fornece alguns hooks e eventos para mutação e query para lidar com erros e outros estados dos efeitos colaterais, o que remove a necessidade de usar hooks como useState e useEffect e os substitui por algumas linhas com React Query.

Créditos

💖 💪 🙅 🚩
oieduardorabelo
Eduardo Rabelo

Posted on May 5, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related