Menu

Renderização condicional no React: if, ternário, && e null

A renderização condicional no React é JavaScript puro: um if, um ternário ou && decide qual JSX um componente retorna. Aprenda cada padrão, o 0 perdido que o && pode imprimir, retornar null e por que esconder um componente não é o mesmo que não renderizá-lo.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Renderização condicional no React significa escolher o que um componente retorna com JavaScript comum: uma instrução if antes do return, um ternário cond ? a : b dentro do JSX ou cond && <Thing /> para mostrar algo ou nada. Não existe sintaxe especial de template para aprender.

Clique no botão e tanto a mensagem quanto o rótulo mudam, porque cada ternário escolhe uma string diferente na próxima renderização. Troque useState(false) por useState(true) e a prévia começa com o login feito.

Instruções if e retornos antecipados

As chaves do JSX aceitam expressões, não instruções, então você não pode escrever {if (x) ...} dentro da marcação. Você pode escrever qualquer if antes do return. Quando um estado inteiro do componente tem outra aparência (carregando, erro, vazio), retorne cedo em cada caso e deixe a marcação principal para o caso normal.

Cada botão coloca a caixa de entrada em um estado diferente, e cada estado tem seu próprio ramo curto e legível. Os retornos antecipados mantêm o caminho feliz no final, sem aninhamento.

Ternários dentro do JSX

Quando só uma pequena parte da marcação muda, um ternário inline a mantém junta: {isOpen ? <CloseIcon /> : <MenuIcon />}. Ternários funcionam bem para duas opções. Ternários aninhados para três ou mais ficam difíceis de ler rapidamente:

// Hard to follow
{status === 'loading' ? <Spinner /> : status === 'error' ? <ErrorBox /> : <List />}

Quando você vir isso, leve a lógica para uma sequência de if antes do return (como acima) ou para um mapa de objeto (mais abaixo).

&& e o 0 perdido

cond && <Thing /> renderiza <Thing /> quando cond é truthy e nada quando é false. Funciona porque o && retorna o lado esquerdo quando ele é falsy, e o React não renderiza nada para false, null e undefined.

A armadilha é que 0 também é falsy, e o React renderiza números. Então count && <Badge /> com uma contagem de 0 coloca um 0 literal na página.

Sem mensagens não lidas, a primeira linha mostra "Broken: 0" enquanto a segunda não mostra nada depois de "Fixed:". Clique em New message e as duas concordam; clique em Mark all read e o 0 volta. A solução é dar ao && um booleano de verdade: unread > 0, items.length > 0 ou Boolean(unread). Uma string vazia '' tem o mesmo problema em princípio, mas é renderizada como nada visível, então você raramente percebe.

Retornando null

Um componente pode retornar null para não renderizar nada. Um banner de aviso que só aparece quando há algo para avisar é um bom exemplo: o pai sempre renderiza <Warning /> e o componente decide.

Observe o console: a função Warning registra em toda renderização, inclusive nas que retornam null. Retornar null pula a saída, não o trabalho. Os hooks e efeitos dele continuam rodando, então, se um componente é caro ou inicia algo (um timer, uma assinatura), decida no pai e simplesmente não o renderize.

Guardando JSX em uma variável

JSX é um valor, então você pode atribuí-lo a uma variável, montá-lo com instruções if e colocá-lo na marcação depois. Isso ajuda quando uma parte de um layout maior depende de várias condições.

function Checkout({ cart, user }) {
    let action;
    if (!user) {
        action = <a href="/login">Log in to check out</a>;
    } else if (cart.length === 0) {
        action = <p>Your cart is empty.</p>;
    } else {
        action = <button>Pay now</button>;
    }

    return (
        <section>
            <h2>Your cart</h2>
            {action}
        </section>
    );
}

Escolhendo entre vários componentes com um objeto

Quando a escolha é "um entre muitos", um objeto que mapeia cada valor para um componente é mais curto que uma longa sequência de if ou um switch, e adicionar um caso é uma linha.

TABS[tab] escolhe um componente, e <Panel /> o renderiza. A variável precisa começar com letra maiúscula: o JSX trata <panel /> como uma tag HTML. Adicione uma entrada notifications em TABS com seu próprio componente e aparece um quarto botão.

Esconder não é o mesmo que não renderizar

Há duas formas de fazer algo desaparecer, e elas se comportam de modo diferente. show && <Counter /> remove o componente da árvore quando show é falso. O React o desmonta e descarta o estado dele, então ele recomeça do zero quando volta. Escondê-lo com CSS (style={{ display: show ? 'block' : 'none' }}) o mantém montado, então o estado sobrevive.

Clique algumas vezes nos dois contadores, desmarque a caixa e marque de novo. O primeiro contador volta para 0 e o segundo continua com o número. Nenhum dos dois está errado: remover é o certo para um formulário que deve começar vazio toda vez, esconder é o certo para abas cuja posição de rolagem ou entrada deve ser mantida. A página sobre renderização explica como o React decide que um componente é o mesmo entre renderizações.

O React 19.2 adiciona uma terceira opção, <Activity mode="hidden">, que esconde os filhos e mantém o estado deles como o CSS faz, e também limpa os efeitos deles até que sejam mostrados de novo.

Props e atributos condicionais

Condições não tratam só de quais elementos aparecem. Qualquer prop pode receber um valor calculado, então um ternário ou uma comparação dentro de um atributo muitas vezes é tudo de que você precisa:

<button disabled={!canSave} className={hasError ? 'field error' : 'field'}>
    Save
</button>
<input aria-invalid={hasError} placeholder={user ? user.email : 'you@example.com'} />

Quando o valor de uma prop é undefined, o React deixa o atributo totalmente de fora, o que é um jeito limpo de adicionar um atributo só às vezes: title={isTruncated ? fullText : undefined}. Para atributos booleanos como disabled e checked, passe true ou false e o React os adiciona ou remove.

Condições em listas

Para deixar itens de fora de uma lista, filtre o array antes de mapeá-lo em vez de retornar null de dentro do map. items.filter((i) => i.done).map(...) diz exatamente o que faz, e a página sobre listas e keys mostra isso em um exemplo funcionando.

Perguntas frequentes

Como escrevo um if dentro do JSX?

Você não pode colocar uma instrução if dentro das chaves do JSX, porque as chaves aceitam expressões. Use um ternário (cond ? a : b) ou && dentro do JSX, ou execute o if antes do return e guarde o JSX em uma variável.

Por que meu componente mostra um 0?

count && <Badge /> retorna o próprio count quando ele é 0, e o React renderiza o número 0. Faça o lado esquerdo ser um booleano de verdade: count > 0 && <Badge />.

Como não renderizo nada no React?

Retorne null do componente, ou coloque null, undefined, false ou true no JSX. O React não renderiza nenhum deles.

Um componente que retorna null ainda executa?

Sim. A função dele executa, os hooks executam e os efeitos disparam. Retornar null só significa que ele não adiciona nada à página. Para pular o trabalho todo, não renderize o componente a partir do pai.

Devo esconder um componente com CSS ou removê-lo?

Removê-lo (show && <Panel />) o desmonta, então o estado dele é descartado e recomeça na próxima vez. Escondê-lo com display: none o mantém montado e preserva o estado. Escolha conforme o estado deva ou não sobreviver.

Ilustração das linguagens de programação do Coddy

Aprenda a programar com o Coddy

COMEÇAR