Especialização Frontend com React & TypeScript • Demonstrações Práticas Executáveis


🎯 Contexto e Objetivo Prático

Consulta resiliente com TanStack Query v5, cache automático, tratamento declarativo de loading/error e refetch em background.


💻 Código Fonte React 19 (TSX)

// useUsersQuery.ts
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";

export interface UserDTO {
  id: string;
  name: string;
  email: string;
  status: "active" | "inactive";
}

// 1. Função de busca pura assíncrona
async function fetchUsersList(): Promise<UserDTO[]> {
  const response = await fetch("/api/v1/users");
  if (!response.ok) {
    throw new Error(`Falha HTTP ${response.status}: Impossível carregar usuários.`);
  }
  return response.json();
}

// 2. Custom Hook tipado consumindo TanStack Query
export function useUsers() {
  return useQuery({
    queryKey: ["users", "list"],
    queryFn: fetchUsersList,
    staleTime: 1000 * 60 * 5, // 5 minutos de cache fresco (Zero refetch desnecessário)
    retry: 2
  });
}

// Componente Consumidor
export function UsersDirectory() {
  const { data: users, isPending, isError, error, refetch } = useUsers();

  if (isPending) return <p className="text-sm text-slate-500">Carregando catálogo...</p>;
  if (isError) return <p className="text-sm text-red-500">Erro: {error.message}</p>;

  return (
    <section>
      <div className="flex justify-between items-center mb-3">
        <h3 className="font-bold text-slate-800">Diretório de Usuários ({users.length})</h3>
        <button onClick={() => refetch()} className="text-xs text-blue-600">↻ Recarregar</button>
      </div>
      <ul className="divide-y divide-slate-100">
        {users.map(u => (
          <li key={u.id} className="py-2 flex justify-between text-sm">
            <span>{u.name}</span>
            <span className="text-slate-400 font-mono text-xs">{u.email}</span>
          </li>
        ))}
      </ul>
    </section>
  );
}

🖥️ Saída de Renderização Visual e Comportamento

[Diretório Reativo com Cache]
Carregando catálogo... (isPending: true)
-> Dados resolvidos em 140ms
Diretório de Usuários (3)     [↻ Recarregar]
Carlos Menezes  carlos@empresa.com
Mariana Rocha   mariana@empresa.com