Skip to main content

Gerenciamento de Estado | React

  • Gerenciamento de Estado | React

Visão Geral

Em aplicações React modernas, o gerenciamento de estado deve ser dividido de forma arquitetural em três categorias distintas:

  • Estado Local
  • Estado Global
  • Server State (HTTP State)

Cada categoria possui responsabilidades bem definidas. Misturar esses domínios aumenta acoplamento, complexidade e custo cognitivo.


Estado Local (useState)

O estado local é restrito ao escopo de um componente.

Quando utilizar

  • Controle de formulários
  • Estados visuais (modal, dropdown, loading local)
  • Toggle de UI
  • Dados efêmeros

Características

  • Escopo isolado
  • Ciclo de vida vinculado ao componente
  • Não compartilhado externamente

Exemplo

import { useState } from "react";

export function Counter() {
const [count, setCount] = useState(0);

return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
);
}

Limitação

Quando múltiplos componentes precisam acessar o mesmo estado, ocorre:

  • Prop drilling
  • Elevação excessiva de estado
  • Complexidade estrutural

Nesse cenário, deve-se migrar para estado global.


Estado Global

O estado global é compartilhado entre múltiplos componentes, independentemente da hierarquia.

Casos de uso

  • Autenticação
  • Usuário logado
  • Tema da aplicação
  • Preferências globais
  • Carrinho de compras

Zustand

Biblioteca minimalista baseada em store central.

import { create } from "zustand";

type Store = {
count: number;
increment: () => void;
};

export const useStore = create<Store>((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));

Uso:

export function Counter() {
const { count, increment } = useStore();
return <button onClick={increment}>{count}</button>;
}

Vantagens

  • API simples
  • Alto desempenho
  • Sem boilerplate
  • Não depende de Context API

Jotai

Modelo baseado em átomos independentes.

import { atom, useAtom } from "jotai";

export const countAtom = atom(0);

Uso:

export function Counter() {
const [count, setCount] = useAtom(countAtom);
return <button onClick={() => setCount((c) => c + 1)}>{count}</button>;
}

Vantagens

  • Granularidade fina
  • Re-renderizações controladas
  • Estrutura declarativa

Server State (HTTP State)

Server state representa dados vindos de APIs externas.

Características

  • Assíncrono
  • Cacheável
  • Pode ficar stale
  • Pode ser invalidado
  • Pode ser sincronizado automaticamente

Não deve ser gerenciado manualmente com useEffect em aplicações complexas.


React Query

Biblioteca especializada em cache e sincronização de dados remotos.

import { useQuery } from "@tanstack/react-query";

export function Users() {
const { data, isLoading } = useQuery({
queryKey: ["users"],
queryFn: async () => {
const res = await fetch("/api/users");
return res.json();
},
staleTime: 1000 * 60, // 1 minuto
});

if (isLoading) return <p>Loading...</p>;

return <pre>{JSON.stringify(data, null, 2)}</pre>;
}

Recursos

  • Cache automático
  • Refetch em background
  • Invalidação manual
  • Controle de staleTime
  • Paginação e infinite queries

SWR

Implementa a estratégia Stale-While-Revalidate.

import useSWR from "swr";

export function Users() {
const { data, error } = useSWR(
"/api/users",
(url) => fetch(url).then((res) => res.json())
);

if (error) return <p>Erro</p>;
if (!data) return <p>Carregando...</p>;

return <pre>{JSON.stringify(data, null, 2)}</pre>;
}

Conceito

Mostra dados em cache imediatamente e revalida em segundo plano.


GraphQL: Apollo Client e URQL

Apollo Client

  • Cache normalizado
  • Controle refinado de queries
  • Suporte a subscriptions

Indicado para aplicações GraphQL complexas.

URQL

  • Mais leve
  • Arquitetura modular
  • Melhor controle de performance

Diferença entre Estado Global e Server State

CritérioEstado GlobalServer State
OrigemClienteServidor
SincronizaçãoManualAutomática
CacheManualNativo
InvalidaçãoManualGerenciada
Re-fetchManualInteligente

Arquitetura Recomendada

Separação clara de responsabilidades:

  • useState → Estado local de UI
  • Zustand / Jotai → Estado compartilhado da aplicação
  • React Query / SWR / Apollo → Dados remotos

Essa divisão reduz acoplamento e melhora previsibilidade arquitetural.