Skip to main content

Renderização Condicional

Trabalhar com renderização condicional no React é bastante simples. Normalmente que trabalha com frameworks e biblitoecas Front-End pode imaginar a utilização de if/else para fazer a renderização de algum elementom as existem formas mais simples.

Ao invés de:

if (isLoggedIn) {
  return <UserGreeting />;
} else {
  return <GuestGreeting />;
}

Você pode utilizar o operador ternário:

return isLoggedIn ? <UserGreeting /> : <GuestGreeting />;

Dessa forma o código fica muito mais limpo e fácil de ler.

Também é possível utilizar o operador && para fazer a renderização condicional:

isLoggedIn && <UserGreeting />;

Algo bem comum no dia-a-dia é utilização de ternários e verificação se uma condição é verdadeira e caso seja renderizar um elemento.

Imagem uma listagem de usuários e você quer renderizar um botão de excluir apenas para usuários que possuem o nível de acesso admin.

const users = [
  { name: "John", role: "admin" },
  { name: "Jane", role: "user" },
  { name: "Mary", role: "user" },
];

const UserList = () => {
  return (
    <ul>
      {users.map((user) => (
        <li key={user.name}>
          {user.name} {user.role === "admin" && <button>Excluir</button>}
        </li>
      ))}
    </ul>
  );
};

Elemento Variável

Você pode utilizar variáveis para armazenar elementos. Isso pode ser útil para renderizar um elemento ou outro dependendo de uma condição.

const UserGreeting = () => <h1>Bem-vindo de volta!</h1>;

const GuestGreeting = () => <h1>Por favor, faça login.</h1>;

const Greeting = ({ isLoggedIn }) => {
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
};

const App = () => {
  const isLoggedIn = true; //image que exista aqui um retorno de um serviço que verifica as credenciais do usuário e o token de acesso
  return <Greeting isLoggedIn={isLoggedIn} />;
};

Boas práticas

Utilização de operadores ternários

Algo muito comum é a utilização de operadores ternários para fazer a renderização condicional do código, porém devemos tomar cuidado pra não deixá-lo muito complexo, dificultando a leitra, manutenção, evolução e testes.

Sem contar que a chance de causar um 🐛 aumenta consideravelmente.

// Algo para EVITAR a ser feito

// algumas importações que foram utilizadas abaixo

function Page({ type = "advanced" }) {
  return (
    <div>
      // highlight-start
      {type === "advanced" ? (
        <div>
          <h1>Level Advanced</h1>
          <p>Texto</p>
          <img src="imagem.png" alt="Imagem" />
          <div>
            <Wallet level={level} />
            <Dashboard />
            <Button action={handle} />
          </div>
        </div>
      ) : type === "basic" ? (
        <div>
          <h1>Level Basic</h1>
          <p>Texto 1</p>
          <p>Texto 2</p>
          <img src="imagem.png" alt="Imagem" />
          <div>
            <Wallet level={level} />
            <Button action={handle} />
          </div>
        </div>
      ) : (
        <div>
          <p>Texto</p>
          <div>
            <CreateAccount />
            <Button action={handle} />
          </div>
        </div>
      )}
      // highlight-end
    </div>
  );
}

O código acima funciona? Sim, perfeitamente.

Mas com a evolução, adição de novos componentes, lógicas e etc, essa abordagem pode ficar bastante confusa, dificultando inclusive o entendimento.

O código acima apresenta alguns problemas:

  • Repetição de código, que leva a um aumento desnecessário da complexidade;
  • Dificuldade de compreensão, tornando o código menos acessível para outros desenvolvedores;
  • Desafios para aplicação de testes unitários, pois é necessário testar todas as condições da página;
  • Falta de componentização, o que poderia simplificar a estrutura do código;
  • Complexidade devido ao uso excessivo de condicionais (ternário, if/else, switch-case, etc.);
  • O código se torna uma "tripa", ou seja, muito extenso e enrolado 🏄.

Isso é algo bastante comum no cotidiano de desenvolvimento. Com facilidade, mais código é adicionado, complicando o entendimento da página.

Uma forma de melhorar o código é a criação de componentes específicos para cada type e criar um mapa de componentes para realizar a renderização baseado em uma propriedade.

// Algo MELHOR a ser feito

// highlight-start
import { AdvancedAccount } from "./AdvancedAccount";
import { BasicAccount } from "./BasicAccount";
import { CreateAccount } from "./CreateAccount";
// highlight-end

function getPageComponent(type) {
  // mapa de componentes
  const components = {
    advanced: AdvancedAccount,
    basic: BasicAccount,
    default: CreateAccount,
  };

  // caso o tipo não exista no mapa, retorna o componente padrão
  return components[type] || components["default"];
}

function Page({ type = "advanced" }) {
  const Component = getPageComponent(type);

  return (
    <div>
      <Component />
    </div>
  );
}

Por que essa abordagem é melhor? Consome mais memória? É mais lenta?

Não, a abordagem é melhor porque deixa o código mais limpo, fácil de ler e entender, além de facilitar a manutenção e evolução do código.

Com a evolução da lógica, podemos simplesmente adicionar novos componentes ao mapa, mantendo o mesmo formato. Isso facilita a adição de testes unitários, pois podemos testar a função getPageComponent isoladamente, passando simplesmente o atributo type, sem ter que renderizar a página várias vezes para cobrir cada caso de uso.

As duas abordagens funcionam? Como já mencionado, sim. Mas é sempre bom pensar em boas práticas para manter o código organizado e fácil de evoluir. É muito importante lembrar que não seremos os únicos a trabalhar em um sistema e, mesmo que fôssemos, com certeza amanhã não vamos lembrar o que estávamos pensando naquele dia do desenvolvimento, tornando necessário revisar todo o código.

É essencial ressaltar que esta prática não é recomendada para todas as situações. Frequentemente, um excesso de condicionais indica problemas na arquitetura do código.

Buscar sempre a simplicidade e a clareza no código é o ideal. O uso de operadores ternários é aceitável, mas é prudente limitá-lo a casos mais específicos e evitar exageros.

Quer mais boas práticas? Clique aqui.