createRoot permite que você crie uma root para exibir componentes React dentro de um nó DOM do navegador.

const root = createRoot(domNode, options?)

Referência

createRoot(domNode, options?)

Chame createRoot para criar uma root React para exibir conteúdo dentro de um elemento DOM do navegador.

import { createRoot } from 'react-dom/client';

const domNode = document.getElementById('root');
const root = createRoot(domNode);

O React criará uma root para o domNode e assumirá o gerenciamento do DOM dentro dele. Depois que você tiver criado uma root, você precisa chamar root.render para exibir um componente React dentro dele:

root.render(<App />);

Um app totalmente construído com React geralmente terá apenas uma chamada createRoot para seu componente root. Uma página que usa “borrifos” de React para partes da página pode ter quantas roots separadas forem necessárias.

Veja mais exemplos abaixo.

Parâmetros

  • domNode: Um elemento DOM. O React criará uma root para este elemento DOM e permitirá que você chame funções na root, como render para exibir conteúdo React renderizado.

  • opcional options: Um objeto com opções para esta root React.

    • opcional onCaughtError: Callback chamado quando o React detecta um erro em um Error Boundary. Chamado com o error detectado pelo Error Boundary e um objeto errorInfo contendo o componentStack.
    • opcional onUncaughtError: Callback chamado quando um erro é lançado e não é detectado por um Error Boundary. Chamado com o error que foi lançado e um objeto errorInfo contendo o componentStack.
    • opcional onRecoverableError: Callback chamado quando o React se recupera automaticamente de erros. Chamado com um error que o React lança e um objeto errorInfo contendo o componentStack. Alguns erros recuperáveis podem incluir a causa original do erro como error.cause.
    • opcional identifierPrefix: Um prefixo de string que o React usa para IDs gerados por useId. Útil para evitar conflitos ao usar várias roots na mesma página.

Retorna

createRoot retorna um objeto com dois métodos: render e unmount.

Ressalvas

  • Se seu app for renderizado no servidor, o uso de createRoot() não será compatível. Use hydrateRoot() em vez disso.
  • Você provavelmente terá apenas uma chamada createRoot em seu app. Se você usar um framework, ele pode fazer essa chamada para você.
  • Quando você quiser renderizar um trecho de JSX em uma parte diferente da árvore do DOM que não seja filho do seu componente (por exemplo, um modal ou uma dica de ferramenta (tooltip)), use createPortal em vez de createRoot.

root.render(reactNode)

Chame root.render para exibir um trecho de JSX (“React node”) no nó DOM do navegador da root React.

root.render(<App />);

O React exibirá <App /> na root e assumirá o gerenciamento do DOM dentro dele.

Veja mais exemplos abaixo.

Parâmetros

  • reactNode: Um React node que você deseja exibir. Isso geralmente será um trecho de JSX como <App />, mas você também pode passar um elemento React construído com createElement(), uma string, um número, null ou undefined.

Retorna

root.render retorna undefined.

Ressalvas

  • Na primeira vez que você chama root.render, o React irá limpar todo o conteúdo HTML existente dentro da root React antes de renderizar o componente React nele.

  • Se o nó DOM da sua root contiver HTML gerado pelo React no servidor ou durante a build, use hydrateRoot() em vez disso, que anexa os manipuladores de eventos ao HTML existente.

  • Se você chamar render na mesma root mais de uma vez, o React atualizará o DOM conforme necessário para refletir o último JSX que você passou. O React decidirá quais partes do DOM podem ser reutilizadas e quais precisam ser recriadas por meio de “combinação” com a árvore renderizada anteriormente. Chamar render na mesma root novamente é semelhante a chamar a função [set (/reference/react/useState#setstate) no componente root: o React evita atualizações desnecessárias do DOM.

  • Although rendering is synchronous once it starts, root.render(...) is not. This means code after root.render() may run before any effects (useLayoutEffect, useEffect) of that specific render are fired. This is usually fine and rarely needs adjustment. In rare cases where effect timing matters, you can wrap root.render(...) in flushSync to ensure the initial render runs fully synchronously.

    const root = createRoot(document.getElementById('root'));
    root.render(<App />);
    // 🚩 The HTML will not include the rendered <App /> yet:
    console.log(document.body.innerHTML);

root.unmount()

Chame root.unmount para destruir uma árvore renderizada dentro de uma root React.

root.unmount();

Um app totalmente construído com React geralmente não terá nenhuma chamada para root.unmount.

Isso é útil principalmente se o nó DOM da sua root React (ou qualquer um de seus ancestrais) puder ser removido do DOM por algum outro código. Por exemplo, imagine um painel de abas jQuery que remove abas inativas do DOM. Se uma aba for removida, tudo dentro dela (incluindo as roots React dentro) também seria removido do DOM. Nesse caso, você precisa dizer ao React para “parar” de gerenciar o conteúdo da root removida chamando root.unmount. Caso contrário, os componentes dentro da root removida não saberão como limpar e liberar recursos globais, como assinaturas.

Chamar root.unmount desmontará todos os componentes na root e “desanexará” o React do nó DOM root, incluindo a remoção de quaisquer manipuladores de eventos ou estado na árvore.

Parâmetros

root.unmount não aceita nenhum parâmetro.

Retorna

root.unmount retorna undefined.

Ressalvas

  • Chamar root.unmount desmontará todos os componentes na árvore e “desanexará” o React do nó DOM root.

  • Depois que você chamar root.unmount, você não poderá chamar root.render novamente na mesma root. Tentar chamar root.render em uma root desmontada lançará um erro “Não é possível atualizar uma root desmontada”. No entanto, você pode criar uma nova root para o mesmo nó DOM depois que a root anterior para esse nó tiver sido desmontada.


Uso

Renderizando um app totalmente construído com React

Se seu app for totalmente construído com React, crie uma única root para todo o seu app.

import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root'));
root.render(<App />);

Normalmente, você só precisa executar este código uma vez na inicialização. Ele irá:

  1. Encontrar o nó DOM do navegador definido no seu HTML.
  2. Exibir o componente React para o seu app dentro.
import { createRoot } from 'react-dom/client';
import App from './App.js';
import './styles.css';

const root = createRoot(document.getElementById('root'));
root.render(<App />);

Se seu app for totalmente construído com React, você não deverá precisar criar mais nenhuma root ou chamar root.render novamente.

A partir deste ponto, o React irá gerenciar o DOM de todo o seu app. Para adicionar mais componentes, aninhá-los dentro do componente App. Quando você precisar atualizar a UI, cada um de seus componentes pode fazer isso usando o state. Quando você precisar exibir conteúdo extra, como um modal ou uma dica de ferramenta (tooltip) fora do nó DOM, renderize-o com um portal.

Note

Quando seu HTML estiver vazio, o usuário verá uma página em branco até que o código JavaScript do app carregue e seja executado:

<div id="root"></div>

Isso pode parecer muito lento! Para resolver isso, você pode gerar o HTML inicial a partir de seus componentes no servidor ou durante a build. Então seus visitantes podem ler texto, ver imagens e clicar em links antes que qualquer código JavaScript seja carregado. Recomendamos usar um framework que faça essa otimização imediatamente. Dependendo de quando ele é executado, isso é chamado de server-side rendering (SSR) ou static site generation (SSG).

Pitfall

Apps que usam server rendering ou static generation devem chamar hydrateRoot em vez de createRoot. O React então hidratará (reutilizará) os nós DOM do seu HTML em vez de destruí-los e recriá-los.


Renderizando uma página parcialmente construída com React

Se sua página não for totalmente construída com React, você pode chamar createRoot várias vezes para criar uma root para cada parte de UI de nível superior gerenciada pelo React. Você pode exibir conteúdo diferente em cada root chamando root.render.

Aqui, dois componentes React diferentes são renderizados em dois nós DOM definidos no arquivo index.html:

import './styles.css';
import { createRoot } from 'react-dom/client';
import { Comments, Navigation } from './Components.js';

const navDomNode = document.getElementById('navigation');
const navRoot = createRoot(navDomNode); 
navRoot.render(<Navigation />);

const commentDomNode = document.getElementById('comments');
const commentRoot = createRoot(commentDomNode); 
commentRoot.render(<Comments />);

Você também pode criar um novo nó DOM com document.createElement() and adicioná-lo ao documento manualmente.

const domNode = document.createElement('div');
const root = createRoot(domNode);
root.render(<Comment />);
document.body.appendChild(domNode); // Você pode adicioná-lo em qualquer lugar do documento

Para remover a árvore React do nó DOM e limpar todos os recursos usados por ela, chame root.unmount.

root.unmount();

Isso é útil principalmente se seus componentes React estiverem dentro de um app escrito em um framework diferente.


Atualizando um componente root

Você pode chamar render mais de uma vez na mesma root. Contanto que a estrutura da árvore de componentes corresponda ao que foi renderizado anteriormente, o React irá preservar o estado. Observe como você pode digitar no input, o que significa que as atualizações de chamadas repetidas de render a cada segundo neste exemplo não são destrutivas:

import { createRoot } from 'react-dom/client';
import './styles.css';
import App from './App.js';

const root = createRoot(document.getElementById('root'));

let i = 0;
setInterval(() => {
  root.render(<App counter={i} />);
  i++;
}, 1000);

Não é comum chamar render várias vezes. Normalmente, seus componentes atualizarão o state em vez disso.

Error no logging em production

Por padrão, o React registra todos os erros no console. Para implementar seu próprio relatório de erros, você pode fornecer as opções opcionais de raiz do manipulador de erros onUncaughtError, onCaughtError e onRecoverableError:

import { createRoot } from "react-dom/client";
import { reportCaughtError } from "./reportError";

const container = document.getElementById("root");
const root = createRoot(container, {
onCaughtError: (error, errorInfo) => {
if (error.message !== "Known error") {
reportCaughtError({
error,
componentStack: errorInfo.componentStack,
});
}
},
});

A opção onCaughtError é uma função chamada com dois argumentos:

  1. O error que foi gerado.
    1. Um objeto errorInfo que contém o componentStack do erro.

Junto com onUncaughtError e onRecoverableError, você pode implementar seu próprio sistema de relatórios de erros:

import { createRoot } from "react-dom/client";
import App from "./App.js";
import {
  onCaughtErrorProd,
  onRecoverableErrorProd,
  onUncaughtErrorProd,
} from "./reportError";

const container = document.getElementById("root");
const root = createRoot(container, {
  // Keep in mind to remove these options in development to leverage
  // React's default handlers or implement your own overlay for development.
  // The handlers are only specfied unconditionally here for demonstration purposes.
  onCaughtError: onCaughtErrorProd,
  onRecoverableError: onRecoverableErrorProd,
  onUncaughtError: onUncaughtErrorProd,
});
root.render(<App />);

Solução de problemas

Eu criei uma raiz, mas nada é exibido

Certifique-se de não ter esquecido de renderizar seu app na raiz:

import { createRoot } from 'react-dom/client';
import App from './App.js';

const root = createRoot(document.getElementById('root'));
root.render(<App />);

Até que você faça isso, nada é exibido.


Estou recebendo um erro: “Você passou um segundo argumento para root.render”

Um erro comum é passar as opções para createRoot para root.render(...):

Console
Aviso: Você passou um segundo argumento para root.render(…) mas ele só aceita um argumento.

Para corrigir, passe as opções de raiz para createRoot(...), não root.render(...):

// 🚩 Errado: root.render aceita apenas um argumento.
root.render(App, {onUncaughtError});

// ✅ Correto: passe opções para createRoot.
const root = createRoot(container, {onUncaughtError});
root.render(<App />);

Estou recebendo um erro: “O contêiner de destino não é um elemento DOM”

Este erro significa que o que você está passando para createRoot não é um nó DOM.

Se não tiver certeza do que está acontecendo, tente registrar:

const domNode = document.getElementById('root');
console.log(domNode); // ???
const root = createRoot(domNode);
root.render(<App />);

Por exemplo, se domNode for null, isso significa que getElementById retornou null. Isso acontecerá se não houver nenhum nó no documento com o ID fornecido no momento da sua chamada. Pode haver alguns motivos para isso:

  1. O ID que você está procurando pode ser diferente do ID que você usou no arquivo HTML. Verifique se há erros de digitação!
  2. A tag <script> do seu bundle não pode “ver” nenhum nó DOM que aparece depois dele no HTML.

Outra forma comum de obter este erro é escrever createRoot(<App />) em vez de createRoot(domNode).


Estou recebendo um erro: “Funções não são válidas como uma criança do React.”

Este erro significa que o que você está passando para root.render não é um componente React.

Isso pode acontecer se você chamar root.render com Component em vez de <Component />:

// 🚩 Errado: App é uma função, não um Componente.
root.render(App);

// ✅ Correto: <App /> é um componente.
root.render(<App />);

Ou se você passar uma função para root.render, em vez do resultado de chamá-la:

// 🚩 Errado: createApp é uma função, não um componente.
root.render(createApp);

// ✅ Correto: chame createApp para retornar um componente.
root.render(createApp());

Meu HTML renderizado no servidor é recriado do zero

Se seu app for renderizado no servidor e incluir o HTML inicial gerado pelo React, você poderá notar que criar uma raiz e chamar root.render exclui todo esse HTML e, em seguida, recria todos os nós DOM do zero. Isso pode ser mais lento, redefine o foco e as posições de rolagem e pode perder outras entradas do usuário.

Apps renderizados no servidor devem usar hydrateRoot em vez de createRoot:

import { hydrateRoot } from 'react-dom/client';
import App from './App.js';

hydrateRoot(
document.getElementById('root'),
<App />
);

Observe que sua API é diferente. Em particular, geralmente não haverá mais uma chamada root.render.