Spec Frontend Com React • Trilha Progressiva em 4 Níveis


🧭 Navegação Pedagógica


🎯 Nível 1: Fundamentos

Problema 13.1 — Consulta de Dados com useQuery e Estados isPending / isError

Contexto: Consulta de Dados com useQuery e Estados isPending / isError no contexto de Data Fetching e Caching com TanStack Query.

Requisitos de Execução:

  1. Criar hook de consulta useQuery({ queryKey: ['produtos'], queryFn: fetchProdutos }).

Resultado Esperado

Dados cacheados com estados de carregamento e erro gerenciados automaticamente.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_13_1_SeuNome
  2. Envie na tarefa: Atividade Cap 13 - Data Fetching e Caching com TanStack Query
🔑 Gabarito de Código & Solução Comentada
// useProdutosQuery.ts
import { useQuery } from '@tanstack/react-query';

export function useProdutos() {
  return useQuery({
    queryKey: ['produtos'],
    queryFn: async () => {
      const res = await fetch('/api/produtos');
      if (!res.ok) throw new Error('Erro ao buscar produtos');
      return res.json();
    },
    staleTime: 1000 * 60 * 5, // 5 minutos
  });
}

🔍 Nível 2: Prática

Problema 13.2 — Mutações e Invalidação de Cache com useMutation e queryClient.invalidateQueries

Contexto: Mutações e Invalidação de Cache com useMutation e queryClient.invalidateQueries no contexto de Data Fetching e Caching com TanStack Query.

Requisitos de Execução:

  1. Implementar mutação de criação de produto que invalide a chave ['produtos'] após o sucesso.

Resultado Esperado

Novo item persistido e lista de produtos revalidada automaticamente em background.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_13_2_SeuNome
  2. Envie na tarefa: Atividade Cap 13 - Data Fetching e Caching com TanStack Query
🔑 Gabarito de Código & Solução Comentada
// useCriarProdutoMutation.ts
import { useMutation, useQueryClient } from '@tanstack/react-query';

export function useCriarProduto() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (novo: { nome: string; preco: number }) => {
      const res = await fetch('/api/produtos', { method: 'POST', body: JSON.stringify(novo) });
      return res.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['produtos'] });
    },
  });
}

⚡ Nível 3: Integração

Problema 13.3 — Atualizações Otimistas (Optimistic Updates) com onMutate

Contexto: Atualizações Otimistas (Optimistic Updates) com onMutate no contexto de Data Fetching e Caching com TanStack Query.

Requisitos de Execução:

  1. Atualizar o estado da UI instantaneamente antes da confirmação do servidor com rollback em caso de falha.

Resultado Esperado

Interface atualizada com zero latência perceptível pelo usuário.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_13_3_SeuNome
  2. Envie na tarefa: Atividade Cap 13 - Data Fetching e Caching com TanStack Query
🔑 Gabarito de Código & Solução Comentada
// optimisticUpdate.ts
onMutate: async (novoItem) => {
  await queryClient.cancelQueries({ queryKey: ['todos'] });
  const snapshotAnterior = queryClient.getQueryData(['todos']);
  queryClient.setQueryData(['todos'], (old: any) => [...old, novoItem]);
  return { snapshotAnterior };
},
onError: (err, novo, context) => {
  queryClient.setQueryData(['todos'], context?.snapshotAnterior);
}

🏆 Nível 4: Desafio Corporativo

Problema 13.4 — Paginação Infinita com useInfiniteQuery

Contexto: Paginação Infinita com useInfiniteQuery no contexto de Data Fetching e Caching com TanStack Query.

Requisitos de Execução:

  1. Implementar scroll infinito de produtos usando useInfiniteQuery e botão de carregar mais.

Resultado Esperado

Páginas subsequentes carregadas e agregadas no cache do TanStack Query.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_13_4_SeuNome
  2. Envie na tarefa: Atividade Cap 13 - Data Fetching e Caching com TanStack Query
🔑 Gabarito de Código & Solução Comentada
// InfiniteScrollList.tsx
import { useInfiniteQuery } from '@tanstack/react-query';

export const InfiniteProdutos = () => {
  const { data, fetchNextPage, hasNextPage } = useInfiniteQuery({
    queryKey: ['produtos-infinitos'],
    queryFn: async ({ pageParam = 1 }) => fetch(`/api/produtos?page=${pageParam}`).then(r => r.json()),
    getNextPageParam: (lastPage, allPages) => lastPage.nextPage ?? undefined,
    initialPageParam: 1,
  });

  return <button onClick={() => fetchNextPage()} disabled={!hasNextPage}>Carregar mais</button>;
};

⬅️ Voltar ao Índice de Exercícios 📚 Sumário de Tópicos