createRoot
createRoot
permite que você crie uma raiz para exibir componentes do React dentro de um nó do DOM do navegador.
const root = createRoot(domNode, options?)
- Referência
- Uso
- Solução de Problemas
- Eu criei uma raiz, mas nada é exibido
- Estou recebendo um erro: “Você passou um segundo argumento para root.render”
- Estou recebendo um erro: “O contêiner de destino não é um elemento DOM”
- Estou recebendo um erro: “Funções não são válidas como um filho do React.”
- Meu HTML renderizado no servidor é recriado do zero
Referência
createRoot(domNode, options?)
Chame createRoot
para criar uma raiz React para exibir conteúdo dentro de um elemento do DOM do navegador.
import { createRoot } from 'react-dom/client';
const domNode = document.getElementById('root');
const root = createRoot(domNode);
O React criará uma raiz para o domNode
e assumirá o gerenciamento do DOM dentro dele. Depois de criar uma raiz, você precisará chamar root.render
para exibir um componente React dentro dela:
root.render(<App />);
Um aplicativo totalmente construído com o React geralmente terá apenas uma chamada createRoot
para seu componente raiz. Uma página que usa “espólios” de React para partes da página pode ter tantas raízes separadas quanto necessário.
Parâmetros
-
domNode
: Um elemento DOM. O React criará uma raiz para este elemento DOM e permitirá que você chame funções na raiz, comorender
para exibir conteúdo React renderizado. -
opcional
options
: Um objeto com opções para esta raiz React.- Canary only opcional
onCaughtError
: Callback chamado quando o React captura um erro em uma Boundary de Erro. Chamado com oerror
capturado pela Boundary de Erro e um objetoerrorInfo
contendo ocomponentStack
. - Canary only opcional
onUncaughtError
: Callback chamado quando um erro é lançado e não capturado por uma Boundary de Erro. Chamado com oerror
que foi lançado e um objetoerrorInfo
contendo ocomponentStack
. - opcional
onRecoverableError
: Callback chamado quando o React se recupera automaticamente de erros. Chamado com umerror
que o React lança e um objetoerrorInfo
contendo ocomponentStack
. Alguns erros recuperáveis podem incluir a causa original do erro comoerror.cause
. - opcional
identifierPrefix
: Um prefixo de string que o React usa para IDs gerados poruseId
. Útil para evitar conflitos ao usar várias raízes na mesma página.
- Canary only opcional
Retorna
createRoot
retorna um objeto com dois métodos: render
e unmount
.
Ressalvas
- Se seu aplicativo é renderizado no servidor, o uso de
createRoot()
não é suportado. UsehydrateRoot()
em vez disso. - Você provavelmente terá apenas uma chamada
createRoot
em seu aplicativo. Se você usar um framework, ele pode fazer essa chamada por você. - Quando você deseja renderizar um pedaço de JSX em uma parte diferente da árvore DOM que não é um filho do seu componente (por exemplo, um modal ou uma tooltip), use
createPortal
em vez decreateRoot
.
root.render(reactNode)
Chame root.render
para exibir um pedaço de JSX (“nó React”) no nó DOM do navegador da raiz React.
root.render(<App />);
O React exibirá <App />
na root
e assumirá o gerenciamento do DOM dentro dela.
Parâmetros
reactNode
: Um nó React que você deseja exibir. Isso geralmente será um pedaço de JSX como<App />
, mas você também pode passar um elemento React construído comcreateElement()
, uma string, um número,null
ouundefined
.
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 raiz React antes de renderizar o componente React dentro dela. -
Se o nó DOM da sua raiz contiver HTML gerado pelo React no servidor ou durante a construção, use
hydrateRoot()
em vez disso, que anexa os manipuladores de eventos ao HTML existente. -
Se você chamar
render
na mesma raiz mais de uma vez, o React atualizará o DOM conforme necessário para refletir o JSX mais recente que você passou. O React decidirá quais partes do DOM podem ser reutilizadas e quais precisam ser recriadas por meio de “correspondê-lo” com a árvore renderizada anteriormente. Chamarrender
novamente na mesma raiz é similar a chamar a funçãoset
no componente raiz: o React evita atualizações desnecessárias no DOM.
root.unmount()
Chame root.unmount
para destruir uma árvore renderizada dentro de uma raiz React.
root.unmount();
Um aplicativo totalmente construído com o React geralmente não terá chamadas para root.unmount
.
Isso é útil principalmente se o nó DOM da sua raiz React (ou qualquer um de seus ancestrais) puder ser removido do DOM por algum outro código. Por exemplo, imagine um painel de guia jQuery que remove guias inativas do DOM. Se uma guia for removida, tudo dentro dela (incluindo as raízes React dentro) também será removido do DOM. Nesse caso, você precisa informar ao React para “parar” de gerenciar o conteúdo da raiz removida chamando root.unmount
. Caso contrário, os componentes dentro da raiz removida não saberão como liberar e liberar recursos globais como assinaturas.
Chamar root.unmount
desmontará todos os componentes na raiz e “desanexará” o React do nó DOM da raiz, incluindo a remoção de quaisquer manipuladores de eventos ou estado na árvore.
Parâmetros
root.unmount
não aceita parâmetros.
Retorna
root.unmount
retorna undefined
.
Ressalvas
-
Chamar
root.unmount
desmontará todos os componentes na árvore e “desanexará” o React do nó DOM da raiz. -
Depois de chamar
root.unmount
, você não pode chamarroot.render
novamente na mesma raiz. Tentar chamarroot.render
em uma raiz desmontada lançará um erro “Não é possível atualizar uma raiz desmontada”. No entanto, você pode criar uma nova raiz para o mesmo nó DOM após a raiz anterior desse nó ter sido desmontada.
Uso
Renderizando um aplicativo totalmente construído com React
Se seu aplicativo é totalmente construído com React, crie uma única raiz para todo o seu aplicativo.
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á:
- Encontrar o nó DOM do navegador definido em seu HTML.
- Exibir o componente React para seu aplicativo dentro dele.
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 aplicativo é totalmente construído com React, você não deve precisar criar mais raízes ou chamar root.render
novamente.
A partir deste ponto, o React gerenciará o DOM de todo o seu aplicativo. Para adicionar mais componentes, aninhá-los dentro do componente App
. Quando você precisar atualizar a interface do usuário, cada um de seus componentes pode fazer isso usando estado. Quando você precisar exibir conteúdo extra, como um modal ou uma tooltip fora do nó DOM, renderize-o com um portal.
Renderizando uma página parcialmente construída com React
Se sua página não estiver totalmente construída com React, você pode chamar createRoot
várias vezes para criar uma raiz para cada peça de UI de nível superior gerenciada pelo React. Você pode exibir conteúdos diferentes em cada raiz chamando root.render
.
Aqui, dois diferentes componentes React 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()
e 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 no 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 aplicativo escrito em um framework diferente.
Atualizando um componente raiz
Você pode chamar render
mais de uma vez na mesma raiz. Desde que a estrutura da árvore de componentes corresponda ao que foi renderizado anteriormente, o React preservará o estado. Note como você pode digitar na entrada, o que significa que as atualizações a partir 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);
É incomum chamar render
várias vezes. Normalmente, seus componentes irão atualizar o estado em vez disso.
Mostrar um diálogo para erros não capturados
Por padrão, o React registrará todos os erros não capturados no console. Para implementar seu próprio relatório de erros, você pode fornecer a opção raiz opcional onUncaughtError
:
import { createRoot } from 'react-dom/client';
const root = createRoot(
document.getElementById('root'),
{
onUncaughtError: (error, errorInfo) => {
console.error(
'Erro não capturado',
error,
errorInfo.componentStack
);
}
}
);
root.render(<App />);
A onUncaughtError opção é uma função chamada com dois argumentos:
- O error que foi lançado.
- Um objeto errorInfo que contém o componentStack do erro.
Você pode usar a opção de raiz onUncaughtError
para exibir diálogos de erro:
import { createRoot } from "react-dom/client"; import App from "./App.js"; import {reportUncaughtError} from "./reportError"; import "./styles.css"; const container = document.getElementById("root"); const root = createRoot(container, { onUncaughtError: (error, errorInfo) => { if (error.message !== 'Known error') { reportUncaughtError({ error, componentStack: errorInfo.componentStack }); } } }); root.render(<App />);
Exibindo erros de Boundary de Erro
Por padrão, o React registrará todos os erros capturados por uma Boundary de Erro em console.error
. Para substituir esse comportamento, você pode fornecer a opção raiz opcional onCaughtError
para lidar com erros capturados por uma Boundary de Erro:
import { createRoot } from 'react-dom/client';
const root = createRoot(
document.getElementById('root'),
{
onCaughtError: (error, errorInfo) => {
console.error(
'Erro Capturado',
error,
errorInfo.componentStack
);
}
}
);
root.render(<App />);
A onCaughtError opção é uma função chamada com dois argumentos:
- O error que foi capturado pela boundary.
- Um objeto errorInfo que contém o componentStack do erro.
Você pode usar a opção de raiz onCaughtError
para exibir diálogos de erro ou filtrar erros conhecidos do registro:
import { createRoot } from "react-dom/client"; import App from "./App.js"; import {reportCaughtError} from "./reportError"; import "./styles.css"; const container = document.getElementById("root"); const root = createRoot(container, { onCaughtError: (error, errorInfo) => { if (error.message !== 'Known error') { reportCaughtError({ error, componentStack: errorInfo.componentStack, }); } } }); root.render(<App />);
Exibindo um diálogo para erros recuperáveis
O React pode automaticamente renderizar um componente uma segunda vez para tentar se recuperar de um erro lançado na renderização. Se bem-sucedido, o React registrará um erro recuperável no console para notificar o desenvolvedor. Para substituir esse comportamento, você pode fornecer a opção raiz opcional onRecoverableError
:
import { createRoot } from 'react-dom/client';
const root = createRoot(
document.getElementById('root'),
{
onRecoverableError: (error, errorInfo) => {
console.error(
'Erro Recuperável',
error,
error.cause,
errorInfo.componentStack,
);
}
}
);
root.render(<App />);
A onRecoverableError opção é uma função chamada com dois argumentos:
- O error que o React lança. Alguns erros podem incluir a causa original como error.cause.
- Um objeto errorInfo que contém o componentStack do erro.
Você pode usar a opção de raiz onRecoverableError
para exibir diálogos de erro:
import { createRoot } from "react-dom/client"; import App from "./App.js"; import {reportRecoverableError} from "./reportError"; import "./styles.css"; const container = document.getElementById("root"); const root = createRoot(container, { onRecoverableError: (error, errorInfo) => { reportRecoverableError({ error, cause: error.cause, componentStack: errorInfo.componentStack, }); } }); root.render(<App />);
Solução de Problemas
Eu criei uma raiz, mas nada é exibido
Certifique-se de que você não esqueceu de realmente renderizar seu aplicativo 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(...)
:
Para corrigir, passe as opções da raiz para createRoot(...)
, não para root.render(...)
:
// 🚩 Errado: root.render só aceita 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”
Esse erro significa que o que você está passando para createRoot
não é um nó DOM.
Se você não tem certeza do que está acontecendo, tente registrá-lo:
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 um nó no documento com o ID dado no momento da sua chamada. Pode haver algumas razões para isso:
- O ID que você está procurando pode diferir do ID que você usou no arquivo HTML. Verifique se não há erros de digitação!
- A tag
<script>
do seu pacote não pode “ver” nenhum nó DOM que aparece depois dela no HTML.
Outra maneira comum de obter esse erro é escrever createRoot(<App />)
em vez de createRoot(domNode)
.
Estou recebendo um erro: “Funções não são válidas como um filho do React.”
Esse 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 aplicativo é renderizado no servidor e inclui o HTML inicial gerado pelo React, você pode notar que criar uma raiz e chamar root.render
exclui todo esse HTML e depois 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.
Aplicativos 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 chamadas root.render
.