React Query (Um pouco de teoria e um pouco de prática)

Mateus
React Brasil
4 min readMar 17, 2023

--

Buenas, pessoal. Passado alguns meses sem escrever (falta de tempo), retorno hoje para falar sobre o React Query.

O que é?

React Query é uma biblioteca de gerenciamento de estados e de requisições de dados, voltado para o React. É uma lib com uma performance muito boa para casos como:

- buscar, fazer armazenamento em cache
- sincronizar async data no aplicativo

Na prática:

Digamos que temos o seguinte problema: Estamos desenvolvendo um app que gerencia algumas tarefas, o famoso todo, como poderemos editar, pegar, escrever ou deletar, teremos uma gama de endpoints que farão essas operações:

get 
post
put
delete

Fazendo isso funcionar:

Para começarmos a utilizar o react-query precisamos instalar ele usando o comando no nosso terminal: (escolha o seu gerenciador de pacote preferido)

yarn add react-query 
npm install react-query
pnpm install react-query

Bom, como falei anteriormente, o react-query é um gerenciador de estados, então teremos que utilizar um Provider para que a children (nosso app) seja capaz de receber informações e lidar com elas conforme necessidade. Uma vez instalado e importado, ficará assim:

import { QueryClient, QueryClientProvider } from "react-query"
import Todo from './components/Todo'

const queryClient = new QueryClient()

export default function App() {
return (
<QueryClientProvider client={queryClient}>
<Todo />
</QueryClientProvider>
)
}

Uma vez que tenhamos feito isso, vamos ter a nossa disposição o hook useQuery, ele vai ser responsável por armazenar em cache a nossa listinha de todo, belê?

Criando nossa lista:

Eu criei um arquivo simples chamado Todo.jsx contendo o seguinte conteúdo:

import React from 'react'

export default function Todo() {
return (
<h1>Todo</h1>
)
}

Bom, agora vamos utilizar o hook que mencionei antes para buscar e guardar no cache a nossa lista de todo.

(Mas mateus, cadê a api fake pra fazer o exemplo?) Tá aqui ó:

{
"todos": [
{
"id": 1,
"title": "Fazer compras",
"completed": false
},
{
"id": 2,
"title": "Estudar para o exame de matemática",
"completed": false
},
{
"id": 3,
"title": "Fazer exercícios",
"completed": true
},
{
"id": 4,
"title": "Ler um livro",
"completed": false
}
]
}

Instale os pacotes:

yarn add axios
yarn add json-server --dev

Axios para lidar com as reqs e o json-srever para simular uma fake api. Chequem a documentação de como usar o json-server, mas é simples.. No meu caso eu fiz o seguinte:

Dentro de api.js eu tenho o seguinte:

import axios from 'axios'

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

export {api}

Para rodar a api fake abra o seu terminal e digite:

yarn json-server --watch db.json -p 3333

Como resultado:

Segue o baile:

Uma vez que temos nossa api rodando é hora de fazer isso funcionar, voltemos ao nosso Todo.jsx, tudo acontece lá.

import React from 'react'
import { useQuery } from 'react-query'
import { api } from '../services/api'

export default function Todo() {
const { isLoading, error, data } = useQuery('todos', async () => {
const response = await api.get('/todos')
return response.data.todos
})

if (isLoading) {
return <div>Carregando...</div>
}

if (error) {
return <div>Erro ao carregar todos</div>
}

return (
<ul>
{data.map((todo) => (
<li key={todo.id}>
{todo.title} - {todo.completed ? 'concluído' : 'pendente'}
</li>
))}
</ul>
)
}

O que tá rolando nesse código?

  1. Estamos utilizando o hook useQuery para trazer para nós os dados que exisitrem dentro da nossa API REST. Uma coisa importante de saber é: Temos uma chave única para o useQuery, no caso, ‘todos’, ela é usada como um identificador para essa consulta a API.
  2. Logo após isso, nós estamos verificando se o nosso dado está carregando, utilizando o isLoading, error, caso carregado com sucesso, renderiza os dados na ul.

Plus:

Isso é um exemplo básico do básico, em partes mais complexas podemos fazer muitas coisas, por exemplo:

Com o R.Query podemos definir limte de cache, configurar do zero toda uma estrutura de atualização.

Entendendo como o React Query olha para o cache:

O cache é uma memória local, ela tem como responsabilidade armazenar os resultados de qualquer consulta anteriormente feita.

Quando realizamos uma consulta, o query fica observando se tal consulta não foi realizada anteriormente e se algum dado está pelo cache. Isso é o natural, mas assim, caso exista algum registro dentro do cache, o React Query vai retornar o que tiver lá, ao invés de fazer todo fluxo de chamada a uma api, por exemplo do jeito clássico:

const myComponent = () => {
const [data, setData] = useState([])
async function handleData() {
const response = await api.get('data')
setData(response.data)
}
}

useEffect(() => {
handleData()
}, [])

Essa jogada do react query melhora um horror o desempenho da aplicação, evita req atrás de req. (Claro, não estou dizendo pra nunca mais usar o effect, até pq isso não faria sentido, cada cenário, atores diferentes)

Ainda sobre o cache:

O React Query gerencia em modo automático o cache, claro, podemos configurar algumas opções, limite de tempo de cache, uma quantidade de itens para ficar em cache, tudo isso é possível também.

Claro, tenha precauções:

É crucial que se trate o cache de forma responsável, qualquer configuração errada vai resultar umas treta chata, principalmente dados desatualizados.

Considerações finais

É uma lib poderosa de fato. Pq melhora de forma significativa o desempenho da nossa aplicação, isso é um fato. Mas é aquela coisa, tenha responsabilidade na hora de usar, e mais do que isso, saiba que não serve pra tudo, no que antecede a chegada dele, sempre existiu outras formas de lidar com cache, vale destacar. Mas em boa parte de cases, sim, ele funciona muito bem.

até mais, pessoal! para quem estiver lendo isso na Sexta (17 de março), bom final de semana.

--

--