Capítulo 4
React: lista e formulário
3 min de leitura 458 palavras 1 gravura
Neste capítulo você vai listar oficinas e acrescentar um item pelo formulário. O projeto-fio é o Ateliê Boa Viagem, ateliê digital fictício em Boa Viagem, Recife.
Seu ponto de partida
Use o exemplo 04-react-lista do pacote anexo e copie inicio/ para uma pasta de prática fora do original. A raiz do exemplo é a referência completa desta etapa.
Use servidor só em 127.0.0.1 quando o README do exemplo pedir HTTP local. Abrir ou testar não publica nada.
Como praticar
Leia → copie ou digite → mude uma coisa → preveja → salve → recarregue → confira. Restaure cada experiência antes da próxima. Faça as atividades antes de abrir as respostas comentadas.

Listas precisam de key estável
Ao mapear arrays, cada filho precisa de key única entre irmãos. Evite o índice se a lista reordena ou remove itens.
Faça na sua cópia
Confira o trecho no contexto do exemplo antes de mudar.
{oficinas.map((o) => <li key={o.id}>{o.nome}</li>)}
Mude uma coisa e preveja
Adicione uma oficina na lista inicial.
Anote o que espera observar antes de salvar e recarregar.
Recarregue e confira
A lista mostra o novo item.
Se não acontecer
Garanta ids únicos.
Formulário controlado
O valor do input vem do estado. onChange atualiza o estado. No submit, previna o envio padrão e atualize a lista.
Faça na sua cópia
Confira o trecho no contexto do exemplo antes de mudar.
<input value={nome} onChange={(e) => setNome(e.target.value)} />
Mude uma coisa e preveja
Limpe o campo após acrescentar.
Anote o que espera observar antes de salvar e recarregar.
Recarregue e confira
O input volta vazio e a lista cresce.
Se não acontecer
Chame preventDefault no submit.
Validação mínima na interface
Não aceite nome vazio. Mensagens curtas e ligadas ao campo ajudam.
Faça na sua cópia
Confira o trecho no contexto do exemplo antes de mudar.
if (!nome.trim()) return;
Mude uma coisa e preveja
Mostre um aviso quando o nome estiver vazio.
Anote o que espera observar antes de salvar e recarregar.
Recarregue e confira
Submit vazio não altera a lista.
Se não acontecer
Confira trim e o return antecipado.
Atividades
Atividade 1
Por que key não deve ser o índice em listas que removem itens?
Atividade 2
O que é um input controlado?
Atividade 3
Onde validar nome vazio neste exemplo?
Respostas comentadas
Resposta da atividade 1
O React pode reutilizar o DOM errado ao reordenar.
Resposta da atividade 2
Seu value vem do estado React e muda via onChange.
Resposta da atividade 3
No handler de submit, antes de atualizar a lista.
O arquivo completo
Referência do exemplo 04-react-lista, reproduzida aqui para que você possa conferir sem sair da página.
styles.css
:root{--ink:#1a1a1a;--bg:#f7f4ef;--brand:#1f3a5f;--accent:#c45c26;--line:#d9d2c5;--focus:#0b57d0}
*{box-sizing:border-box}html{font-family:"Segoe UI",Tahoma,sans-serif;color:var(--ink);background:var(--bg)}
body{margin:0;line-height:1.5}a:focus-visible,button:focus-visible,input:focus-visible{outline:3px solid var(--focus);outline-offset:2px}
.skip{position:absolute;left:-999px}.skip:focus{left:1rem;top:1rem;z-index:10;background:#fff;padding:.5rem}
header,footer{background:var(--brand);color:#fff;padding:1rem 1.25rem}header a,footer a{color:#fff}
main{max-width:52rem;margin:0 auto;padding:1.25rem}h1{color:var(--brand);margin-top:0}
.card{background:#fff;border:1px solid var(--line);padding:1rem;margin:.75rem 0}
button{background:var(--accent);color:#fff;border:0;padding:.55rem 1rem;cursor:pointer}
.board{display:grid;grid-template-columns:repeat(3,4.5rem);gap:.4rem}
.square{width:4.5rem;height:4.5rem;font-size:1.5rem;background:#fff;border:2px solid var(--brand)}
label{display:block;margin:.5rem 0 .2rem;font-weight:600}
input,textarea{width:100%;max-width:28rem;padding:.45rem;border:1px solid var(--line)}
ul.nav{list-style:none;padding:0;display:flex;gap:1rem;flex-wrap:wrap;margin:0}
.status{font-weight:600;margin:.75rem 0}