Menu

Ciclo de vida no React: montar, atualizar, desmontar

Todo componente React monta (aparece), atualiza (renderiza de novo) e desmonta (é removido). Aprenda como cada fase corresponde ao useEffect, aos métodos de ciclo de vida das classes e aos hooks equivalentes, e às fases de render e commit.

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

O ciclo de vida de um componente React tem três fases: montagem (o componente aparece na tela pela primeira vez), atualização (ele renderiza de novo porque o estado, as props ou o context mudaram) e desmontagem (ele é removido). Em componentes de função, você reage a essas fases com useEffect: um efeito com [] executa depois da montagem, um efeito com dependências executa depois das atualizações em que elas mudaram, e a função que um efeito retorna executa na desmontagem.

O console abaixo da prévia mostra cada fase quando ela acontece.

O console começa com render, count = 0 e mounted. Cada clique em Count registra uma renderização e uma atualização. Unmount registra unmounted; Mount de novo recomeça de count = 0, porque o estado foi descartado junto com o componente.

Montagem

Um componente monta na primeira vez que o React o renderiza em um determinado lugar da árvore. O React chama a função, cria os nós do DOM a partir do JSX que ela retorna, insere-os, deixa o navegador pintar a tela e então executa os efeitos do componente.

useEffect(fn, []) é onde você inicia coisas que devem existir enquanto o componente estiver na tela: uma assinatura, um timer, uma conexão, uma primeira requisição de dados. Ele executa depois da pintura, então nunca atrasa o primeiro frame.

Atualização

Um componente atualiza (renderiza de novo) quando:

  • o próprio estado muda,
  • o pai renderiza de novo (por padrão, todos os filhos também renderizam, tenham as props mudado ou não),
  • um context que ele lê muda.

Depois de cada atualização, o React executa os efeitos cujas dependências mudaram. Antes de executar um efeito de novo, ele executa a limpeza anterior desse efeito, então a assinatura antiga fecha antes de a nova abrir. A página sobre renderização trata com mais detalhes do que dispara uma renderização.

Desmontagem

Um componente desmonta quando o pai para de renderizá-lo (como {show && <Counter />} faz acima), quando a key dele muda ou quando a própria raiz é desmontada. O React remove os nós do DOM dele, executa a limpeza de todos os efeitos e descarta o estado. Se o componente aparecer de novo depois, ele é uma instância totalmente nova.

Pais e filhos

O React renderiza de cima para baixo, mas executa os efeitos de baixo para cima. Quando um pai e um filho montam juntos, os efeitos do filho executam primeiro, então o efeito de um pai pode contar com os filhos já totalmente configurados.

A montagem registra render Parent, render Child, Child effect, Parent effect. Aperte Remove e as limpezas executam na ordem inversa: Parent cleanup e depois Child cleanup.

Fases de render e commit

Cada atualização passa por duas fases:

  1. Fase de render. O React chama os seus componentes para calcular o novo JSX e o compara com o resultado anterior. Nada muda na tela ainda. O React pode pausar esse trabalho, executá-lo duas vezes no StrictMode ou descartá-lo, e é por isso que a renderização precisa ser pura: nada de requisições, assinaturas ou mudanças em variáveis externas.
  2. Fase de commit. O React aplica as diferenças ao DOM, conecta as refs e executa as callbacks de useLayoutEffect, tudo antes de o navegador pintar a tela. As callbacks de useEffect executam depois disso, normalmente quando o navegador já pintou. Quando um clique ou outra entrada pontual causou a atualização, o React as executa logo depois dos layout effects, para que o resultado esteja pronto antes do próximo evento.

Cada clique registra as três linhas na mesma ordem. Esses efeitos não têm array de dependências, então executam depois de toda renderização. Adicione [] como segundo argumento aos dois e eles executam só depois da primeira.

Métodos de ciclo de vida de classe e seus equivalentes em hooks

Componentes de classe descrevem o ciclo de vida como métodos com nome. Você vai encontrá-los em código mais antigo e em error boundaries, que ainda precisam de uma classe.

Método de classeQuando executaEquivalente em componente de função
constructoruma vez, antes da primeira renderizaçãouseState(initial), useRef
static getDerivedStateFromPropsantes de toda renderizaçãocalcule o valor durante a renderização ou reinicie com uma key
rendertoda renderizaçãoo corpo da função
componentDidMountdepois que a primeira renderização está no DOMuseEffect(fn, [])
shouldComponentUpdateantes de uma atualização, pode pulá-laReact.memo (ele dá a resposta oposta: "as props são iguais")
getSnapshotBeforeUpdatelogo antes de o DOM mudarnenhum hook direto; useLayoutEffect com uma ref é o mais próximo
componentDidUpdatedepois de cada atualizaçãouseEffect(fn, [deps]) (também executa depois da montagem)
componentWillUnmountantes da remoçãoa limpeza retornada pelo useEffect
getDerivedStateFromError, componentDidCatchquando um filho lança um erronenhum: escreva uma classe de error boundary

Aqui está uma classe que registra cada método enquanto ele executa:

A montagem registra constructor, getDerivedStateFromProps, render, componentDidMount. Um clique registra getDerivedStateFromProps, shouldComponentUpdate, render, getSnapshotBeforeUpdate, componentDidUpdate. Faça shouldComponentUpdate retornar false e os cliques param de atualizar o botão: o estado muda, mas o React pula a renderização. A página sobre componentes de classe mostra como converter uma classe assim em uma função.

Pense em sincronização, não em ciclo de vida

A tabela de hooks é útil para ler código antigo, mas pode levar você a escrever efeitos que copiam hábitos de classes, como um grande efeito "did mount" e um grande efeito "did update". Um efeito se lê melhor como "mantenha esta coisa externa sincronizada com estes valores": conecte a roomId e, quando roomId mudar, desconecte e conecte de novo. Escreva um efeito para cada coisa que você sincroniza, liste os valores que ele usa como dependências e deixe o React decidir quando executá-lo.

Perguntas frequentes

Quais são as fases do ciclo de vida de um componente React?

Montagem (o React cria o componente e coloca o resultado dele na tela), atualização (ele renderiza de novo porque o estado, as props ou o context mudaram) e desmontagem (ele é removido e faz a limpeza).

Qual é o equivalente em hook do componentDidMount?

useEffect(() => { ... }, []). O array de dependências vazio faz com que ele execute uma vez, depois que a primeira renderização está na tela. A função que ele retorna é o equivalente do componentWillUnmount.

Qual é o equivalente em hook do componentDidUpdate?

useEffect com os valores que importam no array de dependências, como [userId]. Ao contrário do componentDidUpdate, ele também executa depois da primeira renderização, então cobre montagem e atualização juntas.

Em que ordem executam os efeitos do pai e do filho?

O React renderiza do pai para baixo, mas executa os efeitos dos filhos para cima: o efeito de um filho executa antes do efeito do pai. Na desmontagem, a limpeza do pai executa antes da do filho.

O que são as fases de render e commit?

Na fase de render, o React chama os seus componentes para descobrir como a tela deve ficar; ele pode pausar ou descartar esse trabalho. Na fase de commit, ele aplica as mudanças ao DOM e executa os layout effects; os efeitos comuns executam depois disso, normalmente quando o navegador já pintou a tela.

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

Aprenda a programar com o Coddy

COMEÇAR