DEV Community

Eduardo Rabelo
Eduardo Rabelo

Posted on • Edited on

6 1

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

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (1)

Collapse
 
wlcpereira profile image
Wallace Nascimento Pereira

Parabéns pelo artigo. Irei testa-lo aqui, em algumas POCs.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay