Programação Por Equipe DevBras

Capa do artigo: Lista vazia que explica o que houve e qual é o próximo passo

Lista vazia que explica o que houve e qual é o próximo passo

Separe os quatro tipos de vazio (primeiro uso, busca sem resultado, filtro demais e erro), escreva a frase certa para cada um e pare de mostrar tela branca.

A pessoa digita "notebok" na busca de pedidos e a área de resultados fica branca. Ela não sabe se o sistema travou, se a internet caiu ou se simplesmente não existe pedido com esse nome. Três hipóteses, nenhuma confirmada, e o próximo clique é no botão de atualizar ou no chat do suporte.

A resposta curta: todo lugar que pode ficar vazio precisa de uma frase que diga por que está vazio e o que a pessoa pode fazer agora. "Nenhum pedido encontrado para 'notebok'. Confira a grafia ou limpe os filtros." Isso resolve a ambiguidade em uma linha. E o vazio de erro nunca pode usar a mesma frase do vazio de "não tem nada".

Por que o vazio confunde tanto

Interface comunica por presença. Quando aparece uma lista, a pessoa entende que deu certo. Quando aparece um aviso vermelho, entende que deu errado. Quando não aparece nada, ela não recebe sinal nenhum, e silêncio é compatível com qualquer explicação, inclusive "quebrou".

No código, o problema nasce de um detalhe: o componente recebe um array e faz um laço sobre ele. Array vazio gera zero itens, e ninguém escreveu o caso zero porque nos dados de teste sempre havia algo. O pior acontece quando a requisição falha e o código transforma o erro em array vazio, com um catch que devolve []. Aí "não tem pedido" e "o servidor caiu" ficam visualmente idênticos.

Há ainda o estado de carregamento. Se a lista começa vazia e só depois chega o dado, a pessoa vê por meio segundo a mensagem "nenhum pedido" e depois a lista aparece. Ela aprende que a mensagem de vazio mente.

Os quatro vazios que você precisa distinguir

Vamos usar um caso só: a tela "Meus pedidos" de uma loja pequena, com busca por produto e filtro por status. Ela pode ficar sem itens por quatro motivos diferentes, e cada um pede uma frase diferente.

1. Primeiro uso: ainda não existe nada

Cliente recém-cadastrado, nenhum pedido feito. A mensagem explica o que vai aparecer ali e oferece o caminho, se houver: "Você ainda não fez nenhum pedido. Quando comprar, ele aparece aqui com o status da entrega." Um link para a loja faz sentido porque é o próximo passo real dessa pessoa.

2. Busca sem resultado

Existem pedidos, mas nenhum bate com o termo. Repita o termo buscado, para a pessoa ver o erro de digitação, e diga como ampliar: "Nenhum pedido com 'notebok'. Confira a grafia ou busque por parte do nome."

3. Filtro demais

A busca está vazia, mas os filtros "Cancelado" e "Últimos 7 dias" juntos não retornam nada. Diga quais filtros estão ativos e ofereça um botão que limpa todos de uma vez. Esse é o vazio que mais gera chamado, porque a pessoa esquece que deixou um filtro ligado na visita anterior.

4. Erro ao carregar

A requisição falhou. Isso não é vazio, é erro, e a mensagem diz isso: "Não conseguimos carregar seus pedidos agora. Tente de novo em instantes." Com botão de tentar de novo. Jamais "Você ainda não fez nenhum pedido" para alguém que tem vinte.

Como implementar sem misturar os estados

  1. Modele o estado da tela com um campo explícito: carregando, erro ou pronto. Não deduza o estado pelo tamanho do array.
  2. Quando estiver pronto e o array vier vazio, decida qual dos vazios é olhando a busca e os filtros que foram enviados, não os que estão na tela agora.
  3. Peça ao servidor uma informação a mais quando for barato: se o cliente tem algum pedido no total. Isso separa "primeiro uso" de "filtro demais" sem adivinhação.
  4. Escreva uma frase por tipo de vazio, com uma ação concreta, e revise com alguém que não é do time.
  5. Anuncie a mudança para leitor de tela numa região aria-live="polite", para quem não vê a lista sumir.

Um exemplo em JavaScript puro, sem framework, que você adapta para React, Vue ou Blazor sem mudar a lógica:

function mensagemDeVazio(estado) {
  if (estado.status === 'erro') {
    return {
      texto: 'Não conseguimos carregar seus pedidos agora.',
      acao: { rotulo: 'Tentar de novo', tipo: 'recarregar' }
    };
  }
  if (estado.status !== 'pronto' || estado.itens.length > 0) return null;

  if (estado.totalDoCliente === 0) {
    return {
      texto: 'Você ainda não fez nenhum pedido. Quando comprar, ele aparece aqui.',
      acao: { rotulo: 'Ir para a loja', tipo: 'link', href: '/loja' }
    };
  }
  if (estado.filtrosAtivos.length > 0) {
    return {
      texto: 'Nenhum pedido com os filtros: ' + estado.filtrosAtivos.join(', ') + '.',
      acao: { rotulo: 'Limpar filtros', tipo: 'limpar-filtros' }
    };
  }
  return {
    texto: 'Nenhum pedido com "' + estado.buscaEnviada + '". Confira a grafia.',
    acao: { rotulo: 'Limpar busca', tipo: 'limpar-busca' }
  };
}

Repare em dois detalhes. O erro é testado primeiro, então uma falha nunca cai no texto de primeiro uso. E a busca usada na frase é buscaEnviada, o termo que gerou a resposta, não o que está no campo neste instante. Se a pessoa continuou digitando, a frase ainda corresponde ao resultado mostrado. Esse descompasso entre campo e resposta é o tema de busca que espera a pessoa pausar.

No HTML, a região que anuncia fica fora do bloco que é recriado:

<p aria-live="polite" id="status-lista"></p>
<ul id="lista-pedidos"></ul>

Quando a lista termina de carregar, você escreve no parágrafo algo como "12 pedidos" ou "Nenhum pedido com 'notebok'". Quem usa leitor de tela ouve o resultado sem precisar procurar.

O que o servidor precisa devolver

O vazio honesto depende de a API não esconder erro. Se o endpoint de pedidos responde 200 com lista vazia quando o banco caiu, nenhum cuidado na tela salva a situação. Erro de servidor volta como 500 ou 503, e o front trata como erro. A lista do que cada código significa está em códigos de status HTTP.

Outro ponto: se a lista é paginada, página vazia no meio da navegação geralmente é sinal de paginação por deslocamento quebrada, não de falta de dado. Vale ler paginação que não pula registros antes de culpar o texto.

O que não colocar no lugar do vazio

Existe a tentação de preencher o buraco com qualquer coisa. Produtos em destaque, artigos sem relação, o banner da home. Parece que a tela ficou "rica", mas a pessoa veio buscar um pedido e recebe propaganda. Ela continua sem saber se o pedido existe.

Sugestão só entra quando tem relação direta com o que foi buscado, como "Você quis dizer 'notebook'?" quando o sistema realmente tem esse dado. Ilustração simpática também é aceitável, desde que a frase venha junto e seja a parte mais visível.

Erros comuns

  • Converter erro em array vazio no catch. A pessoa lê "nenhum pedido" quando o servidor caiu e acha que perdeu as compras.
  • Mostrar a mensagem de vazio durante o carregamento. Ela pisca antes da lista e ensina que a mensagem não é confiável.
  • Usar uma frase genérica para todos os casos. "Nada por aqui" não diz se é filtro, busca ou conta nova, e a pessoa não sabe o que mudar.
  • Esquecer os filtros ativos. Filtro salvo da visita anterior zera a lista e ninguém lembra que ele está ligado.
  • Preencher o vazio com conteúdo sem relação. A pessoa não recebe a resposta e ainda perde tempo lendo o que não pediu.
  • Oferecer ação que ela não pode executar. Botão "Criar projeto" para quem não tem permissão gera um segundo erro logo depois do primeiro.

Checklist

  • O estado da tela é explícito (carregando, erro, pronto), e não deduzido do tamanho do array.
  • Primeiro uso, busca sem resultado, filtro demais e erro têm frases diferentes.
  • A frase de busca repete o termo que gerou a resposta.
  • Com filtro ativo, a tela lista os filtros e oferece limpar todos.
  • Falha da API aparece como erro com botão de tentar de novo.
  • A API devolve código de erro quando falha, nunca 200 com lista vazia.
  • Uma região aria-live anuncia a quantidade de resultados.
  • Toda ação sugerida está disponível para aquela pessoa.

Faça agora o teste mais barato do seu sistema: busque um termo impossível, como "xyzxyz", na tela mais usada. A frase que aparece explica, sozinha, por que a lista está vazia e o que fazer em seguida?

Avalie este artigo

Referência: https://www.nngroup.com/articles/empty-state-interface-design/