Usando o Activity na prática

O React 19.2 trouxe o componente Activity, que resolve de um jeito diferente aquele problema clássico de mostrar ou esconder um componente na tela. Testei na prática e vou te mostrar como ele funciona.

react tecnico 5 min de leitura

O React 19.2 saiu no começo de outubro e trouxe alguns recursos novos. Um dos mais interessantes é o componente Activity, que veio com alguns detalhes um pouco estranhos. Vou explicar como ele funciona, mostrar na prática e comentar sobre uma decisão técnica meio esquisita que o time do React tomou.

O jeito antigo de mostrar ou esconder um componente

Antes de ver o Activity, vale relembrar como a gente resolvia isso até então. Uma state booleana controla se o componente aparece ou não:

const [isShowing, setIsShowing] = useState(false);

E no JSX, uma condicional decide se renderiza o conteúdo:

{isShowing && <Example />}

Isso funciona, mas tem um efeito colateral: quando isShowing vira false, o React desmonta o componente por completo. Se esse componente tiver um contador interno, por exemplo, esse estado se perde. Ao mostrar de novo, ele volta zerado, porque foi renderizado do zero.

function Example() {
  const [count, setCount] = useState(0);
 
  return (
    <div>
      <div>Contagem: {count}</div>
      <button onClick={() => setCount((c) => c + 1)}>+</button>
    </div>
  );
}

Clica algumas vezes no +, esconde o componente, mostra de novo: a contagem volta para zero. Isso acontece porque desmontar e remontar não é "esconder", é destruir e criar de novo.

Entra o Activity

O Activity resolve isso de um jeito diferente. Em vez de tirar o componente da árvore, ele mantém o componente montado, só controla se ele está visível ou não.

import { Activity } from "react";
 
<Activity mode={isShowing ? "visible" : "hidden"}>
  <Example />
</Activity>;

A prop mode aceita dois valores: "visible" ou "hidden". Com mode="hidden", o conteúdo não aparece na tela, mas ele continua montado. O estado interno do componente se mantém preservado na memória.

Testando o mesmo contador de antes, agora dentro do Activity: clica até chegar em 6, esconde, mostra de novo. A contagem continua em 6, porque o componente nunca foi desmontado de verdade.

O que acontece com o useEffect

Aqui está o detalhe mais importante pra entender o Activity. Quando o mode está em "hidden", o componente já foi renderizado, só que o useEffect dele não dispara.

useEffect(() => {
  console.log("efeito rodou");
}, []);

Com o componente escondido, esse console.log não aparece. Assim que o mode muda para "visible", o efeito dispara. Ao esconder de novo, o efeito de cleanup roda, mas o componente continua vivo na memória, esperando ser mostrado de novo.

Ou seja, existem duas coisas acontecendo em paralelo:

  • O estado do componente, que fica preservado o tempo todo, esteja visível ou escondido.
  • O efeito do componente, que só dispara quando o componente está visível.

Por que isso é útil

A vantagem fica clara em cenários onde o componente escondido faz alguma busca de dados fora do useEffect, ou quando você quer que o conteúdo já esteja pronto assim que for exibido, sem aquele momento de loading.

Com a condicional antiga, o componente nem existe enquanto está escondido. Quando você decide mostrar, ele é criado do zero: se ele carrega uma lista de posts de uma API, por exemplo, o usuário vai ver um loading acontecendo ali na hora.

Com o Activity, o componente já pode estar processando o que precisa processar enquanto está escondido (exceto o que estiver dentro do useEffect, que só dispara quando ele fica visível). Quando o usuário manda mostrar, o conteúdo já está pronto, e só o efeito dispara.

A escolha estranha do mode como string

Repara que a prop mode só tem dois valores possíveis: "visible" ou "hidden". Isso é, na prática, um comportamento booleano. Faria mais sentido uma prop como show, recebendo true ou false:

<Activity show={isShowing}>
  <Example />
</Activity>

Seria menos código e não precisaria da condicional pra montar a string. Não existe uma explicação oficial do React pra essa escolha, mas a hipótese mais razoável é a seguinte: hoje o Activity só tem dois modos, mas o time do React pode querer adicionar um terceiro modo no futuro, algo como um modo de loading. Usando uma string desde o início, dá pra adicionar novos valores sem quebrar quem já está usando "visible" e "hidden". Com um booleano, essa porta fica fechada.

Faz sentido como estratégia de design de API, mesmo parecendo estranho hoje, quando só existem dois valores possíveis.

Vale a pena usar

O Activity é um componente bom pra situações em que você precisa preservar o estado de algo que está sendo escondido e mostrado com frequência: abas, modais, listas que somem e voltam. Ele evita aquelas gambiarras que a gente fazia antes, como criar um componente próprio só pra guardar o estado por fora enquanto o conteúdo fica escondido por dentro.

O ponto de atenção é lembrar que ele mantém memória ocupada enquanto o componente está escondido, então não é pra usar em tudo, só onde preservar o estado realmente traz benefício.