A renderização condicional é um recurso poderoso do React que permite aos desenvolvedores renderizar componentes com base em determinadas condições.

É um conceito fundamental que desempenha um papel crucial na criação de aplicativos web dinâmicos e interativos.

Neste guia abrangente, vamos nos aprofundar na renderização condicional no React, abordando técnicas básicas e avançadas com exemplos para que você entenda corretamente.

Entendendo a renderização condicional no React

A renderização condicional no React permite que os desenvolvedores controlem dinamicamente o conteúdo exibido na tela com base em valores específicos que podem ser armazenados em uma variável, estado ou props.

Isso pode ser extremamente útil em cenários em que você deseja mostrar ou ocultar determinados elementos da interface do usuário, alterar o layout de uma página ou renderizar conteúdo diferente com base nas interações do usuário.

A renderização condicional é importante nos aplicativos React porque permite criar interfaces de usuário dinâmicas e interativas que podem responder a dados variáveis e interações do usuário em tempo real.

Ela também ajudará a melhorar o desempenho e a eficiência dos aplicativos, pois evita a renderização de componentes ou elementos desnecessários.

Técnicas básicas para renderização condicional

Há várias técnicas básicas que você pode usar para a renderização condicional no React. Vamos explorar cada uma delas em detalhes.

Uso da instrução if para renderização condicional

Uma das maneiras mais diretas de implementar a renderização condicional no React é usar a tradicional declaração if.

if (condition) {
    return <p>Expression 1</p>;
  } else {
    return <p>Expression 2</p>;
  }

A instrução if do JavaScript pode ser usada dentro do método render() do seu componente para renderizar condicionalmente o conteúdo com base em uma determinada condição.

Por exemplo, você pode usar a instrução if para exibir um spinner de carregamento enquanto espera que os dados sejam carregados:

import { useState, useEffect } from 'react';
import Spinner from './Spinner';

const MyComponent = () => {
  const [isLoading, setIsLoading] = useState(true);
  const [data, setData] = useState(null);

  useEffect(() => {
    // Fetch data from an API
    fetch('https://example.com/data')
      .then((response) => response.json())
      .then((data) => {
        setData(data);
        setIsLoading(false);
      });
  }, []);

  if (isLoading) {
    return <Spinner />;
  }

  return <div>{/* Render the data here */}</div>;
};

export default MyComponent;

Neste exemplo, MyComponent obtém dados de uma API usando o hook useEffect. Enquanto aguardamos o carregamento dos dados, exibimos um componente Spinner usando a instrução if.

Outro exemplo pode ser a renderização de uma interface de usuário alternativa quando ocorrer um erro durante a renderização do componente:

const MyComponent = ({ data }) => {
  if (!data) {
    return <p>Something went wrong. Please try again later.</p>;
  }

  return <div>{/* Render the data here */}</div>;
};

export default MyComponent;

Neste código, temos um MyComponent que recebe uma propriedade data. Se a propriedade data for falsa, renderizaremos uma mensagem de erro usando a instrução if.

Por fim, você pode exibir conteúdo diferente para diferentes roles de usuário com a instrução if:

const MyComponent = ({ user }) => {
  if (user.role === 'admin') {
    return <p>Welcome, admin!</p>;
  } else if (user.role === 'user') {
    return <p>Welcome, user!</p>;
  } else {
    return <p>You are not authorized to access this page.</p>;
  }
};

export default MyComponent;

Neste código, temos um MyComponent que recebe uma propriedade user. Dependendo da propriedade user.role, exibimos conteúdo diferente usando a instrução if.

Uso do operador ternário para renderização condicional

Outra maneira concisa de implementar a renderização condicional no React é usar o operador ternário (?) dentro do JSX.

O operador ternário permite que você escreva uma instrução if-else inline compacta especificando 3 operandos. O primeiro operando é a condição, enquanto os outros dois são as expressões. Se a condição for true, a primeira expressão será executada; caso contrário, a segunda expressão.

Por exemplo, você pode renderizar diferentes componentes com base em uma propriedade:

import ComponentA from './ComponentA';
import ComponentB from './ComponentB';

const ExampleComponent = ({ shouldRenderComponentA }) => {
  return (
    <div>
      {shouldRenderComponentA ? <ComponentA /> : <ComponentB />}
    </div>
  );
};

export default ExampleComponent;

Neste código, temos um ExampleComponent que recebe uma prop chamado shouldRenderComponentA. Usamos o operador ternário para renderizar condicionalmente ComponentA ou ComponentB com base no valor da prop.

Você também pode renderizar textos diferentes com base em um estado:

import { useState } from 'react';

const ExampleComponent = () => {
  const [showMessage, setShowMessage] = useState(false);

  return (
    <div>
      <button onClick={() => setShowMessage(!showMessage)}>
        {showMessage ? 'Hide message' : 'Show message'}
      </button>
      {showMessage ? <p>Hello, world!</p> : null}
    </div>
  );
};

export default ExampleComponent;

Neste exemplo, usamos o operador ternário para renderizar condicionalmente um texto diferente, dependendo do valor do estado showMessage. Quando o botão é clicado, o valor de showMessage é alternado, e o texto é exibido ou ocultado de acordo.

Por fim, você pode renderizar um spinner de carregamento enquanto os dados estão sendo obtidos:

import { useState, useEffect } from 'react';
import Spinner from './Spinner';

const ExampleComponent = () => {
  const [isLoading, setIsLoading] = useState(true);
  const [data, setData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
      const jsonData = await response.json();
      setData(jsonData);
      setIsLoading(false);
    };
    fetchData();
  }, []);

  return (
    <div>
      {isLoading ? <Spinner /> : <p>{data.title}</p>}
    </div>
  );
};

export default ExampleComponent;

Neste exemplo, usamos o operador ternário para renderizar condicionalmente um spinner de carregamento enquanto os dados estão sendo obtidos de uma API. Quando os dados estiverem disponíveis, renderizamos a propriedade title usando o operador ternário.

Uso dos operadores lógicos AND e OR para renderização condicional

Você também pode usar os operadores lógicos AND (&&) e OR (||) para implementar a renderização condicional no React.

O operador lógico AND permite renderizar um componente somente se uma determinada condição for verdadeira, enquanto o operador lógico OR permite que você renderize um componente se uma das condições for verdadeira.

Esses operadores são úteis quando você tem condições simples que determinam se um componente deve ser renderizado ou não. Por exemplo, se você quiser renderizar um botão somente se um formulário for válido, poderá usar o operador lógico AND da seguinte forma:

import { useState } from 'react';

const FormComponent = () => {
  const [formValues, setFormValues] = useState({ username: "", password: "" });

  const isFormValid = formValues.username && formValues.password;

  const handleSubmit = (event) => {
    event.preventDefault();
    // Submit form data
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={formValues.username}
        placeholder="Type Username..."
        onChange={(e) =>
          setFormValues({ ...formValues, username: e.target.value })
        }
      />
      <br />
      <input
        type="password"
        value={formValues.password}
        placeholder="Type Password..."
        onChange={(e) =>
          setFormValues({ ...formValues, password: e.target.value })
        }
      />
      {isFormValid && <button type="submit">Submit</button>}
    </form>
  );
};

export default FormComponent;

Neste exemplo, temos um FormComponent que possui um formulário com dois campos de entrada para username e password. Estamos usando o hook useState para gerenciar os valores do formulário e a variável isFormValid para verificar se ambos os campos de entrada têm valores. Usando o operador lógico AND (&&), renderizamos o botão de envio somente se isFormValid for verdadeiro (true). Isso garante que o botão seja ativado somente quando o formulário for válido.

Da mesma forma, você pode usar o operador OR para renderizar uma mensagem de carregamento se os dados ainda estiverem sendo carregados, ou uma mensagem de erro se ocorrer um erro:

import React, { useEffect, useState } from 'react';

const DataComponent = () => {
  const [data, setData] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [errorMessage, setErrorMessage] = useState('');

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        setData(data);
      } catch (error) {
        setErrorMessage('An error occurred while fetching data.');
      } finally {
        setIsLoading(false);
      }
    };

    fetchData();
  }, []);

  return (
    <>
      {errorMessage || isLoading ? (
        <p>{errorMessage || 'Loading...'}</p>
      ) : (
        <ul>
          {data.map((item) => (
            <li key={item.id}>{item.name}</li>
          ))}
        </ul>
      )}
    </>
  );
};

export default DataComponent;

Neste exemplo, um DataComponent obtém dados de uma API usando fetch e os exibe em uma lista. Estamos usando o hook useState para gerenciar os dados, o estado de carregamento e a mensagem de erro. Usando o operador lógico OR (||), podemos renderizar uma mensagem de carregamento ou uma mensagem de erro se uma de suas condições for verdadeira. Isso garante que o usuário veja uma mensagem indicando o estado atual do processo de obtenção de dados.

Usar os operadores lógicos AND e OR para renderização condicional no React é uma maneira concisa e legível de lidar com condições simples. No entanto, é melhor usar outras abordagens, como as declarações switch, para uma lógica mais complexa.

Técnicas avançadas para renderização condicional

A renderização condicional no React pode ser mais complexa, dependendo dos requisitos do seu aplicativo. Aqui estão algumas técnicas avançadas que você pode usar para a renderização condicional em cenários mais complexos.

Uso de instruções Switch para renderização condicional

Embora as instruções if e os operadores ternários sejam abordagens comuns para renderização condicional, às vezes uma instrução switch pode ser mais apropriada, especialmente quando você lida com condições múltiplas.

Um exemplo:

import React from 'react';
const MyComponent = ({ userType }) => {
  switch (userType) {
    case 'admin':
      return <p>Welcome, admin user!</p>;
    case 'user':
      return <p>Welcome, regular user!</p>;
    default:
      return <p>Please log in to continue.</p>;
  }
};
export default MyComponent;

Neste código, uma instrução switch é usada para renderizar o conteúdo condicionalmente com base na propriedade userType. Essa abordagem pode ser útil quando você lida com múltiplas condições, oferecendo uma maneira mais organizada e legível de lidar com lógicas complexas.

Renderização condicional com o React Router

O React Router é uma biblioteca popular para lidar com o roteamento do lado do cliente em aplicativos React. O React Router permite renderizar componentes condicionalmente com base no caminho atual.

Aqui está um exemplo de implantação de renderização condicional usando o React Router:

import { useState } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

import Home from './components/Home';
import Login from './components/Login';
import Dashboard from './components/Dashboard';
import NotFound from './components/NotFound';

const App = () => {
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/login">
          <Login setIsLoggedIn={setIsLoggedIn} />
        </Route>
        {isLoggedIn ? (
          <Route path="/dashboard" component={Dashboard} />
        ) : (
          <Route component={NotFound} />
        )}
      </Switch>
    </Router>
  );
};

export default App;

Neste código, estamos usando o estado isLoggedIn para renderizar condicionalmente o componente Dashboard, se o usuário estiver conectado, ou o componente NotFound se o usuário não estiver conectado. O componente Login define o estado isLoggedIn como true quando o usuário faz login com sucesso.

Observe que estamos usando a propriedade children do componente <Route> para passar o componente Login e a função setIsLoggedIn. Isso nos permite passar props para o componente Login sem especificá-lo na prop path.

Resumo

A renderização condicional é uma técnica poderosa no React que permite atualizar dinamicamente a interface do usuário com base em diferentes condições.

Dependendo da complexidade da lógica da interface de usuário do seu aplicativo, você pode escolher a abordagem que melhor atenda às suas necessidades.

Lembre-se de manter seu código limpo, organizado e legível, e sempre teste exaustivamente sua lógica de renderização condicional para garantir que funcione conforme esperado em diferentes cenários.

Você está procurando a solução de hospedagem ideal para seus aplicativos React? Experimente a hospedagem de aplicativos da Kinsta gratuitamente!

Joel Olawanle Kinsta

Joel is a Frontend developer working at Kinsta as a Technical Editor. He is a passionate teacher with love for open source and has written over 200 technical articles majorly around JavaScript and it's frameworks.