createRoot
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
- 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 uma criança do React.”
- Meu HTML renderizado no servidor é recriado do zero
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.
Parâmetros
-
domNode
: Um elemento DOM. O React criará uma root para este elemento DOM e permitirá que você chame funções na root, comorender
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 oerror
detectado pelo Error Boundary e um objetoerrorInfo
contendo ocomponentStack
. - opcional
onUncaughtError
: Callback chamado quando um erro é lançado e não é detectado por um Error Boundary. 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 roots na mesma página.
- opcional
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. UsehydrateRoot()
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 decreateRoot
.
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.
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 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 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. Chamarrender
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 afterroot.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 wraproot.render(...)
influshSync
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á chamarroot.render
novamente na mesma root. Tentar chamarroot.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á:
- Encontrar o nó DOM do navegador definido no seu HTML.
- 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.
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:
- O error que foi gerado.
-
- 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(...)
:
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:
- O ID que você está procurando pode ser diferente do ID que você usou no arquivo HTML. Verifique se há erros de digitação!
- 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
.