Pular para o conteúdo
Cursos

DevClub

LógicaFront-endBack-endMobile

IA Club

IA na prática
Estudar programaçãoEstudar IA

Aula 4 de 6

Listas, keys e filtros no React

Renderize coleções com map, escolha keys estáveis e derive uma lista filtrada sem duplicar nem modificar o estado original.

44 minutos · leitura + prática · nível iniciante

Ao terminar esta aula, você vai conseguir

  • Transformar arrays em elementos com map
  • Explicar como uma key preserva a identidade de um item
  • Derivar filtros a partir do estado existente
O componente App se divide nos componentes Header, Lista e Botão.

Dados de interface costumam chegar como arrays: tarefas, produtos, mensagens. React permite transformar cada item em JSX com map. Para acompanhar cada elemento entre renderizações, você também fornece uma key, um identificador estável e único entre os irmãos daquela lista.

Pense num guarda-volumes: cada mala recebe uma etiqueta que continua com ela mesmo quando as malas mudam de prateleira. A key cumpre esse papel de identidade. O limite é que a key não fica visível ao usuário nem é passada automaticamente como prop; ela é uma informação usada pelo React durante a reconciliação.

Transforme dados em elementos

Mantenha os dados separados da apresentação e aplique map:

jsx
const tarefas = [
  { id: 't1', titulo: 'Estudar JSX', concluida: true },
  { id: 't2', titulo: 'Praticar listas', concluida: false },
];

function ListaTarefas() {
  return (
    <ul>
      {tarefas.map((tarefa) => (
        <li key={tarefa.id}>{tarefa.titulo}</li>
      ))}
    </ul>
  );
}

Cada execução do callback devolve um <li>. A key precisa ser única apenas entre os itens irmãos daquela lista, mas deve permanecer associada à mesma tarefa. Um id vindo dos dados é a escolha usual.

Índice não é identidade

Usar key={indice} pode parecer suficiente. Se a lista nunca reordena, insere ou remove itens, talvez não apareça problema. Quando essas operações existem, o índice passa a representar outra tarefa e React pode preservar estado ou foco no elemento errado. Um valor aleatório é ainda pior: muda em cada renderização e faz todos os itens parecerem novos.

Se o componente filho também precisa do id, passe explicitamente:

jsx
<ItemTarefa key={tarefa.id} id={tarefa.id} titulo={tarefa.titulo} />

key e id têm trabalhos diferentes. A primeira serve ao React; a segunda é uma prop disponível para ItemTarefa.

Filtro é valor derivado

Se o estado já contém todas as tarefas e o filtro atual, não guarde uma terceira cópia chamada tarefasVisiveis. Calcule durante a renderização:

jsx
const tarefasVisiveis = tarefas.filter((tarefa) => {
  if (filtro === 'pendentes') return !tarefa.concluida;
  if (filtro === 'concluidas') return tarefa.concluida;
  return true;
});

Isso mantém uma fonte de verdade. Quando tarefa ou filtro mudam, a nova renderização deriva a lista correta. Para coleções realmente grandes e cálculos caros, existe otimização; primeiro comprove que existe custo antes de adicionar complexidade.

Atualize um item com map

Para alternar uma tarefa, crie um novo array. map devolve um objeto novo apenas para o item encontrado e mantém os outros:

jsx
setTarefas((atuais) => atuais.map((tarefa) =>
  tarefa.id === id
    ? { ...tarefa, concluida: !tarefa.concluida }
    : tarefa
));

Esse comportamento preserva snapshots anteriores e permite ao React comparar referências. No laboratório, alterne tarefas enquanto observa cada filtro. A quantidade apresentada deve sempre resultar dos dados, não de um contador mantido separadamente.

Uma lista também precisa representar o vazio. Se o array original não tem itens, explique como criar o primeiro. Se apenas o filtro não encontra correspondências, informe que existem itens fora daquele recorte. Tecnicamente os dois casos têm length === 0, mas comunicam situações diferentes. Derive a mensagem comparando tarefas.length e tarefasVisiveis.length, sem criar mais um estado booleano.

Como microprática, anote os ids antes e depois de reordenar o array. Cada tarefa deve conservar o próprio id; só a posição muda. Depois repita usando índices como keys e explique por que a identidade deixaria de acompanhar o dado.

Erro comum: usar map sem retornar JSX

Ao abrir chaves no callback, você precisa escrever return. O código tarefas.map(tarefa => { <li>...</li> }) devolve undefined. Use parênteses para retorno implícito ou chaves com retorno explícito. Também confira a key no elemento mais externo devolvido pelo map.

Na missão, conclua um item no filtro pendentes. Ele deve desaparecer desse recorte, continuar presente em todas e aparecer em concluídas. Se o dado sumir do estado original, você filtrou destrutivamente. Na próxima aula, vamos permitir que o usuário inclua novas tarefas por um formulário controlado.

Laboratório ao vivo

Filtro de tarefas com keys estáveis

Alterne o filtro e marque tarefas como concluídas. Adicione uma tarefa no código e confirme que seu id é único e que os três filtros continuam corretos.

Pronto para testar
Resultado

Pare e pense

Qual valor é a melhor key para uma tarefa que pode mudar de posição?

Escolha uma resposta
Missão da aula

Faça sem copiar

Crie cinco tarefas, filtros todas e pendentes e uma ação de concluir. A missão passa quando concluir um item o remove apenas do filtro pendentes.

Fontes para consultar

Terminou a missão?

Marque apenas quando você conseguir explicar o conceito e concluir o desafio. O progresso fica salvo somente neste navegador.

Próxima: Formulário controlado no React: entrada e validação →