Fundamentos de React
TP3 completo com fundamentos, questões 1-16, implementação orientada a evidência e roteiro de defesa técnica.
▼
BASE
Introdução e Escopo do TP3
Alinhar o enunciado ao resultado esperado: entender, implementar, validar e explicar.
Este material foi elaborado para servir como guia de aprendizagem, e não como coleção de respostas prontas. O foco é conduzir o aluno do entendimento do enunciado até a construção da solução, para que cada resposta seja reproduzida, validada e explicada com clareza.
As questões do TP3 exigem competências centrais de React: criação de componentes, uso de props, organização visual da interface, listas, estado, interação com usuário e consumo de APIs. O objetivo não é decorar comandos, e sim aprender a relação entre dados, estado e renderização.
Ao longo das seções, cada exercício segue um padrão didático: o que a questão pede, quais conceitos são cobrados, como pensar, qual estrutura usar, como validar e como explicar oralmente. Isso reduz erro de entrega incompleta e melhora a defesa técnica.
- Q1-Q3: componentes de mensagem com props e default.
- Q4-Q5: telas de login e criação de conta.
- Q6-Q8: cartões/listas de contato e endereço.
- Q9-Q12: fluxo com API,
useState,useEffecte listas. - Q13-Q16: categorias/refeições e surpresa com APIs externas.
▼
EX.01
Fundamentos Que Sustentam Todas as Questões
Consolidar o mínimo técnico para resolver o TP3 sem tentativa e erro.
- Componentes React e reutilização.
- Props para dados de entrada e parametrização.
useStatepara dado mutável local.useEffectpara carregamento inicial e dependente.mappara listas comkeyestável.- Renderização condicional para carregamento, erro e vazio.
- Inputs e selects controlados.
fetch+response.json().- Dado derivado versus estado redundante.
- CSS suficiente para legibilidade e organização visual.
Regra de ouro: antes de criar um novo estado, pergunte se o valor pode ser derivado de estados já existentes. Isso evita complexidade desnecessária.
// Exemplo de dado derivado
const usuarioSelecionado =
usuarios.find((u) => String(u.id) === usuarioId) || null;
▼
EX.02
Estrutura de Projeto e Componentes-Base
Padronizar arquitetura para evitar retrabalho na implementação das 16 questões.
src/
componentes/
msg/Erro.jsx, Atencao.jsx, Sucesso.jsx
contatos/Contato.jsx, Endereco.jsx
posts/ListaPosts.jsx
refeicoes/ListaCategorias.jsx
paginas/
Ex01 ... Ex16
App.jsx
main.jsx
Antes de começar a codar, o aluno precisa entender a lógica da organização do projeto. O TP3 pede um único projeto React, mas esse projeto não deve virar um arquivo gigante e confuso. A ideia correta é separar o que é página de teste do que é componente reutilizável. As páginas ficam em
src/paginas porque cada uma representa um exercício sendo testado. Os componentes ficam em src/componentes porque são peças reaproveitáveis da interface, como mensagens, cartões, listas e formulários.
O
App.jsx funciona como ponto de teste. Nele, você importa uma página por vez e renderiza apenas aquela que está estudando naquele momento. Isso ajuda a validar exercício por exercício, evita confusão visual e respeita o enunciado, que pede um único projeto com as páginas sendo chamadas no App.jsx. Em termos práticos, a página resolve o exercício; os componentes sustentam a página.
Regra prática de organização: se um trecho da interface pode ser reutilizado, ele deve virar componente. Se um arquivo existe apenas para testar um exercício inteiro, ele pode ficar em
src/paginas. Essa separação melhora leitura, manutenção e defesa técnica.
Erro comum: colocar tudo dentro de
App.jsx. Isso até pode funcionar em casos muito pequenos, mas enfraquece a estrutura, dificulta a reutilização e faz o aluno perder a noção de componente como unidade de interface.
Checklist de estrutura correta: existe um único projeto React; o
App.jsx renderiza uma página por vez; os componentes reutilizáveis estão separados por tema; cada página importa apenas o que precisa; e a navegação entre exercícios acontece comentando e descomentando a chamada correspondente.
Q1-Q3 reaproveitam o mesmo padrão de componente de mensagem com mudança de estilo e default. Q6-Q8 reaproveitam o padrão de cartão para contato/endereço. Q11-Q12 reaproveitam lista de posts com fontes diferentes de dados.
Organização por componente reduz acoplamento, facilita teste por questão e melhora explicação técnica na apresentação.
▼
EX.03
Q1-Q3: Mensagens de Erro, Atenção e Sucesso
Aplicar props, default value e estilização para componentes de feedback.
O que a questão pede: componente visual com
titulo e mensagem por props, com fallback para o título.export default function Erro({ titulo = "ERRO", mensagem }) {
return (
<div className="msg-card erro">
<h3>{titulo}</h3>
<p>{mensagem}</p>
</div>
);
}
- Q2 e Q3 seguem o mesmo padrão mudando default e classe CSS.
- Conceito central: componente parametrizado por props.
- Validação: sem enviar
titulo, o default deve aparecer corretamente.
▼
EX.04
Q4-Q5: Telas de Login e Criação de Conta
Construir interface de formulário estilizada, sem exigir autenticação real.
As questões pedem interface organizada (labels, inputs e botão), não backend de autenticação.
export default function Login() {
return (
<div className="auth-box">
<h2>Login</h2>
<form className="auth-form">
<label>Email</label>
<input type="email" />
<label>Senha</label>
<input type="password" />
<button type="submit">Entrar</button>
</form>
</div>
);
}
Q5 reaproveita a mesma base adicionando nome e confirmação de senha.
Erro comum: entregar apenas inputs sem hierarquia visual e sem classes CSS coerentes.
▼
EX.05
Q6-Q8: Cartões e Listas de Contato/Endereço
Trabalhar props com objeto, lista com
map e dados simulados com Faker.const contatosFixos = Array.from({ length: 5 }, () => ({
id: faker.string.uuid(),
nome: faker.person.fullName(),
email: faker.internet.email(),
telefone: faker.phone.number(),
}));
{contatosFixos.map((contato) => (
<Contato key={contato.id} contato={contato} />
))}
- Q6: cartão de contato a partir de objeto por props.
- Q7: lista de cartões com dados fixos gerados pelo Faker.
- Q8: cartão de endereço com CEP, logradouro, complemento, bairro, localidade e UF.
Boa prática: gerar lista fixa fora do componente para evitar recriação de dados a cada render.
▼
EX.06
Q9: Consulta de CEP (ViaCEP)
Combinar input controlado, validação, chamada de API e renderização condicional.
const [cep, setCep] = useState("");
const [endereco, setEndereco] = useState(null);
const [erro, setErro] = useState("");
const cepLimpo = cep.replace(/\D/g, "");
if (cepLimpo.length !== 8) {
setErro("CEP inválido.");
return;
}
Esta questão é o primeiro ponto do TP em que o aluno realmente precisa articular estado, evento, API e renderização condicional ao mesmo tempo. O raciocínio completo é este: o usuário digita um CEP; esse valor fica guardado em estado; ao clicar no botão, o React executa uma função assíncrona; essa função limpa o texto digitado, valida se existem 8 dígitos, consulta a API do ViaCEP e, se tudo der certo, salva o endereço retornado em estado. Quando o estado muda, a interface é renderizada novamente, e o componente de endereço passa a aparecer na tela.
Repare que aqui existem três estados com papéis diferentes.
cep guarda a entrada do usuário. endereco guarda o resultado válido da API. erro guarda a mensagem de falha, caso algo dê errado. Essa separação é importante porque cada estado responde a uma pergunta diferente: o que o usuário digitou? qual foi o resultado da consulta? houve algum problema?
Estrutura mental correta: input controlado -> clique no botão -> sanitização do CEP -> validação ->
fetch -> response.json() -> atualização do estado -> renderização do componente Endereco.
Erros comuns: tentar consultar sem limpar traços e pontos; esquecer que a API pode retornar
erro: true; tentar renderizar o cartão de endereço antes de existir um objeto válido; e tratar o input como não controlado, perdendo o valor digitado no fluxo da interface.
Como validar corretamente: digite um CEP válido e confirme se o cartão aparece com CEP, logradouro, complemento, bairro, localidade e UF. Depois teste um CEP inválido e confirme se a página exibe uma mensagem de erro em vez de tentar renderizar dados inexistentes.
- Sem CEP válido, não chama API.
- Se API retornar erro, exibe mensagem clara ao usuário.
- Se retornar endereço, renderiza cartão de endereço.
Erro comum: não limpar caracteres não numéricos e gerar consulta inválida.
▼
EX.07
Q10-Q12: Usuários e Posts com Efeito Dependente
Controlar seleção de usuário e carregar dados dinamicamente sem estado redundante.
useEffect(() => {
async function carregarUsuarios() {
const response = await fetch("https://jsonplaceholder.typicode.com/users");
setUsuarios(await response.json());
}
carregarUsuarios();
}, []);
useEffect(() => {
async function carregarPosts() {
if (!usuarioId) {
setPosts([]);
return;
}
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts?userId=${usuarioId}`
);
setPosts(await response.json());
}
carregarPosts();
}, [usuarioId]);
Este bloco reúne três exercícios que parecem parecidos, mas não são iguais. A Q10 pede carregar usuários, permitir a seleção em um dropdown e mostrar os dados do usuário escolhido. A Q11 pede exibir a lista completa de posts. Já a Q12 combina as duas ideias: primeiro o usuário escolhe uma pessoa, depois a aplicação busca apenas os posts relacionados a essa pessoa. O ponto central aqui é entender que existe um dado base e um dado dependente.
Na Q10, o dado base é a lista de usuários. Ela deve ser carregada uma vez, na montagem do componente, com
useEffect(..., []). O valor escolhido no dropdown fica em estado, normalmente como usuarioId. A partir desse estado e da lista já carregada, é possível derivar o usuário selecionado com find. Isso é importante: o usuário selecionado não precisa, necessariamente, de um novo estado. Em muitos casos, ele pode ser calculado a partir do que já existe.
Na Q11, a lógica é mais simples: a página só precisa buscar os posts e renderizar a lista. Já na Q12 aparece o efeito dependente. O segundo
useEffect só deve rodar quando usuarioId mudar. É exatamente por isso que a dependência é [usuarioId]. Sem usuário selecionado, a lista de posts deve ficar vazia. Com usuário selecionado, a aplicação consulta a API usando ?userId=... e atualiza o estado de posts.
Regra didática importante: primeiro carrega a lista base; depois reage à escolha do usuário; só então carrega os dados filtrados. Esse fluxo é mais limpo do que tentar buscar tudo ao mesmo tempo sem critério.
Erros comuns: guardar em estado um dado que poderia ser derivado com
find; tentar carregar posts antes de existir usuarioId; esquecer de limpar os posts quando o usuário volta para a opção vazia; e não perceber que Q10, Q11 e Q12 exigem três comportamentos diferentes, mesmo compartilhando parte da lógica.
Como validar: na Q10, selecione usuários diferentes e confirme se os dados exibidos mudam. Na Q11, a lista de posts deve aparecer completa. Na Q12, a seleção do usuário deve alterar a lista de posts exibida, mostrando apenas os posts daquele usuário.
- Q10: dropdown de usuários e exibição do selecionado.
- Q11: lista completa de posts.
- Q12: posts filtrados por usuário selecionado.
Como pensar: primeiro carrega a lista base (usuários), depois aplica efeito dependente para dados filtrados (posts).
▼
EX.08
Q13-Q15: Categorias, Refeições e Receita Aleatória
Trabalhar TheMealDB com dropdown dependente e ação aleatória orientada por evento.
// Q14: carregar refeições por categoria
const response = await fetch(
`https://www.themealdb.com/api/json/v1/1/filter.php?c=${encodeURIComponent(categoriaSelecionada)}`
);
// Q15: surpresa de receita
const randomResponse = await fetch(
"https://www.themealdb.com/api/json/v1/1/random.php"
);
Aqui o aluno precisa entender que o TheMealDB não devolve sempre o mesmo formato de resposta. Na consulta de categorias, a lista real vem em
data.categories. Na consulta de refeições por categoria, a lista real vem em data.meals. Já na receita aleatória, o retorno também vem em data.meals, mas com um único item dentro do array. Ou seja: a API é a mesma família, mas o payload muda conforme o endpoint.
A Q13 é a mais simples desse grupo: buscar categorias e renderizar nome e descrição. A Q14 exige duas etapas ligadas entre si: carregar categorias para o dropdown e, depois, quando o usuário escolhe uma delas, buscar as refeições correspondentes. Já a Q15 não depende de seleção; depende apenas de um botão que dispara uma ação assíncrona e exibe o resultado aleatório.
O raciocínio da Q14 é especialmente importante. O dropdown é controlado por estado. Quando
categoriaSelecionada muda, um useEffect dependente dessa categoria precisa rodar. Esse efeito consulta o endpoint filter.php?c=... e atualiza a lista de refeições. Se nenhuma categoria estiver selecionada, a lista deve ser esvaziada para evitar resultado antigo na tela.
Fluxo correto da Q14: carregar categorias -> selecionar categoria -> atualizar estado -> disparar efeito dependente -> buscar refeições -> renderizar nova lista.
Erros comuns: fixar uma categoria no código e ignorar a seleção do usuário; esquecer que a resposta pode vir sem refeições; tratar a receita aleatória como lista comum; e não distinguir os três formatos de payload usados neste bloco.
Como validar: na Q13, a lista de categorias deve mostrar nome e descrição. Na Q14, trocar a categoria no dropdown deve alterar a lista de refeições exibida. Na Q15, clicar em
Me Surpreenda deve mostrar uma nova receita, com dados coerentes do mesmo prato.
- Q13: listar categorias com nome e descrição.
- Q14: ao trocar categoria, atualizar lista de refeições.
- Q15: botão
Me Surpreendapara receita aleatória.
Erro comum: fixar categoria no código e ignorar a seleção do usuário.
▼
EX.09
Q16: País Aleatório com Rest Countries
Buscar país aleatório exibindo pelo menos 5 campos com payload enxuto.
const response = await fetch(
"https://restcountries.com/v3.1/all?fields=name,capital,region,population,flags,cca3"
);
const data = await response.json();
const indice = Math.floor(Math.random() * data.length);
setPais(data[indice]);
Esta questão parece simples, mas ensina uma habilidade importante: buscar uma coleção grande, escolher um item aleatório e exibir apenas os campos úteis para a interface. O fluxo é: consultar a API de países, converter a resposta para JSON, obter um índice aleatório, selecionar um país do array e guardar esse objeto em estado. Depois disso, a renderização condicional exibe os dados escolhidos.
O ideal aqui é escolher campos que mostrem variedade de tipos de dado. Um conjunto bom é: nome comum, nome oficial, capital, região, população e bandeira. Isso permite trabalhar texto simples, texto aninhado, array opcional e imagem. Esse exercício também é ótimo para mostrar que nem todo campo vem em formato plano. Por exemplo, a capital costuma vir como array, e por isso o acesso mais seguro é
capital?.[0].
Boa prática: usar o parâmetro
fields= no endpoint para pedir apenas os campos que a interface vai usar. Isso reduz payload, deixa o exemplo mais claro e ajuda o aluno a entender melhor o formato esperado dos dados.
Erros comuns: esquecer que a capital pode não existir; tentar usar o objeto inteiro sem escolher os campos relevantes; não usar renderização condicional; e tratar um array de países como se a resposta fosse um único objeto.
Como validar: a cada clique em
Me Surpreenda, a tela deve mostrar um país plausível com pelo menos cinco dados visíveis e uma bandeira correspondente. O conteúdo pode repetir eventualmente, mas o mecanismo deve estar correto.
- Campos recomendados: nome, nome oficial, capital, região, população e bandeira.
- Uso de
fields=reduz payload e simplifica o consumo. - Renderização condicional evita acesso a campo inexistente antes da resposta.
▼
EX.10
Roteiro de Defesa Técnica e Erros Frequentes
Garantir que o aluno consiga explicar e justificar qualquer questão do TP3.
Roteiro de explicação: o que a questão pede, qual componente foi criado, quais dados entram, se os dados vêm de props/estado/API, qual evento altera estado e como foi validado.
Exemplo (Q12): select controlado guarda
usuarioId; useEffect dependente busca posts por userId; resultado vai para estado e a lista renderiza só os posts do usuário selecionado.
- Confundir props com estado.
- Fazer tudo em
App.jsxsem componentização. - Esquecer
keyem listas. - Não tratar caso vazio/erro de API.
- Criar estado demais quando o valor é derivável.
- Entregar interface sem estilização mínima exigida.
▼
EX.11
Checklist de Correção Antes da Entrega
Fechar o TP3 com rastreabilidade de requisito por questão.
- Q1-Q3 com título default funcionando por props.
- Q4-Q5 com formulário organizado e estilizado.
- Q6-Q8 com cartões de contato/endereço completos.
- Q7 com Faker +
map+key. - Q9 com consulta de CEP e tratamento de erro.
- Q10 com dropdown de usuários e exibição dinâmica.
- Q11 com lista de posts da API.
- Q12 com posts filtrados por usuário selecionado.
- Q13-Q14 com categorias e refeições por seleção.
- Q15 com receita aleatória.
- Q16 com país aleatório e mínimo de 5 dados.
Se todos os itens acima estiverem comprovados, o aluno está apto a entregar e explicar o TP3 com segurança.
▼
CHECK
Validação Final de Conformidade
Consolidar aderência editorial, técnica e semântica antes de publicar.
Antes de considerar o TP fechado, o aluno precisa verificar não só se "apareceu alguma coisa na tela", mas se cada tipo de competência realmente foi demonstrado. O objetivo deste check não é apenas confirmar entrega visual. É confirmar domínio técnico mínimo.
- Props: os componentes recebem dados de fora quando o enunciado pede parametrização?
- Estado: inputs, seleções, resultados de API e mensagens de erro estão em
useStatequando precisam mudar? - Dado derivado: algum valor foi calculado a partir de outro, em vez de virar estado redundante?
- Listas: toda lista dinâmica foi renderizada com
mapekeyestável? - Efeitos: carregamentos iniciais usam
useEffectcom dependências corretas? - API: o código usa
fetch,response.json()e leitura correta do payload? - Renderização condicional: erro, vazio, seleção e resultado aparecem apenas quando fazem sentido?
- Estilo: os componentes estão visualmente organizados, legíveis e compatíveis com a ideia de "estilizado"?
Se o aluno consegue responder "sim" para esse bloco inteiro e ainda explicar o caminho de dados de cada página, então ele não apenas montou a solução: ele entendeu a solução.
- Estrutura no padrão do acervo: BASE + EX.01..EX.11 + CHECK.
- Título final aplicado:
Fundamentos de React. - Conteúdo cobrindo fundamentos, Q1..Q16, erros e checklist.
- Identidade visual, navegação e scripts compartilhados preservados.
Página pronta para publicação final com foco em ensino completo, validação e defesa técnica.