createRoot te permite crear una raíz para mostrar componentes de React dentro de un nodo del DOM del navegador.

const root = createRoot(domNode, options?)

Referencia

createRoot(domNode, options?)

Llama a createRoot para crear una raíz de React y mostrar contenido dentro de un elemento del DOM del navegador.

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

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

React creará una raíz para el nodo del DOM (domNode) y tomará el control del manejo del DOM dentro de él. Después de crear una raíz, se necesita llamar a root.render para mostrar un componente de React dentro de él:

root.render(<App />);

Una aplicación construida completamente con React suele llamar createRoot una vez para su componente de raíz. Una página que utiliza un poco de React para unas partes de la página puede tener tantas raíces como sean necesarias.

Ver más ejemplos abajo.

Parámetros

  • domNode: Un elemento del DOM. React creará una raíz para este elemento del DOM y te permite que puedas llamar funciones en la raíz, como render y mostrar el contenido renderizado por React.

  • opcional options: Un objeto que contiene opciones para esta raíz de React.

    • Canary only optional onCaughtError: Callback called when React catches an error in an Error Boundary. Called with the error caught by the Error Boundary, and an errorInfo object containing the componentStack.
    • Canary only optional onUncaughtError: Callback called when an error is thrown and not caught by an Error Boundary. Called with the error that was thrown, and an errorInfo object containing the componentStack.
    • optional onRecoverableError: Callback called when React automatically recovers from errors. Called with an error React throws, and an errorInfo object containing the componentStack. Some recoverable errors may include the original error cause as error.cause.
    • opcional identifierPrefix: prefijo de tipo string que React utiliza para IDs generados por useId. Útil para evitar conflictos cuando se utilizan múltiples raíces en la misma página.

Devuelve

createRoot devuelve un objeto con dos métodos: render y unmount.

Advertencias

  • Si tu aplicación se renderiza por el servidor, usar createRoot() no es permitido. En su lugar, utiliza hydrateRoot().
  • Probablemente, solo se llamará createRoot una vez en tu aplicación. Si utilizas un framework, puede que haga esta llamada por ti.
  • Cuando quieres renderizar una pieza de JSX en otra parte del árbol del DOM que no es un hijo de tu componente (por ejemplo, un modal o un tooltip), usa createPortal en vez de createRoot.

root.render(reactNode)

Llama a root.render para mostrar una pieza de JSX («node de React») en el nodo del DOM del navegador de la raíz de React.

root.render(<App />);

React mostrará <App /> en la raíz (root) y se encargará de administrar el DOM dentro de ella.

Ver más ejemplos abajo.

Parámetros

  • reactNode: Un Nodo de React que deseas mostrar. Por lo general, será una pieza de JSX como <App />, pero también puedes pasar un elemento de React construido con createElement(), un string, un número, null, o undefined.

Devuelve

root.render devuelve undefined.

Advertencias

  • La primera vez que llamas a root.render, React borrará todo el contenido HTML existente dentro de la raíz de React antes de renderizar el componente de React dentro de ella.

  • Si el nodo del DOM de tu raíz contiene HTML generado por React en el servidor o durante la compilación , usa hydrateRoot() en su lugar, que adjunta los controladores de eventos al HTML existente.

  • Si llamas a render en la misma raíz más de una vez, React actualizará el DOM según sea necesario para reflejar el último JSX que pasaste. React decidirá qué partes del DOM se pueden reutilizar y cuáles deben ser recreadas para «emparejarlo» con el árbol renderizado previamente. Llamar a render en la misma raíz nuevamente es similar a llamar a la función set en el componente raíz: React evita actualizaciones del DOM innecesarias.


root.unmount()

Llama a root.unmount para destruir un árbol renderizado dentro de una raíz de React.

root.unmount();

Una aplicación completamente construida con React usualmente no tendrá ninguna llamada a root.unmount.

Esto es útil sobre todo si el nodo del DOM de tu raíz de React (o cualquiera de sus ancestros) puede ser eliminado del DOM por algún otro código. Por ejemplo, imagina un panel de pestañas de jQuery que elimine las pestañas inactivas del DOM. Si se elimina una pestaña, todo lo que contiene (incluidas las raíces de React) también se eliminará del DOM. En ese caso, debes decirle a React que «detenga» la administración del contenido de la raíz eliminada con la llamada a root.unmount. Si no, los componentes dentro de la raíz eliminada no sabrán cómo limpiar y liberar recursos globales como suscripciones.

Llamar a root.unmount desmontará todos los componentes en la raíz y «separará» React del nodo del DOM raíz, incluida la eliminación de cualquier controlador de evento o estado en el árbol.

Parámetros

root.unmount no acepta ningún parámetro.

Devuelve

root.unmount devuelve undefined.

Advertencias

  • Llamar a root.unmount desmontará todos los componentes en el árbol y «separará» React de la raíz del nodo del DOM.

  • Una vez que llames a root.unmount, no podrás volver a llamar a root.render en la misma raíz. Intentar llamar a root.render en una raíz desmontada generará el error «Cannot update an unmounted root» («No se puede actualizar una raíz desmontada»). Sin embargo, puedes crear una nueva raíz para el mismo nodo DOM después de que se haya desmontado la raíz anterior para ese nodo.


Uso

Renderizar una aplicación construida completamente con React

Si tu aplicación está construida completamente con React, crea una raíz única para toda tu aplicación.

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

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

Usualmente, solo necesitarás ejecutar este código una vez al inicio. Este código:

  1. Encontrará el nodo del DOM del navegador definido en tu HTML.
  2. Mostrará dentro el componente de React para tu aplicación.
import { createRoot } from 'react-dom/client';
import App from './App.js';
import './styles.css';

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

Si tu aplicación está construida completamente con React, no deberías necesitar crear más raíces, o llamar a root.render otra vez.

A partir de este punto, React administrará el DOM de tu aplicación entera. Para agregar más componentes, anídalos dentro del componente de la aplicación App. Cuando necesitas actualizar la interfaz de usuario (UI), cada uno de tus componentes puede lograrlo con el uso de estado. Cuando necesitas mostrar contenido adicional como un modal o globos de ayuda fuera del nodo del DOM, renderízalo con un portal.

Nota

Cuando tu HTML está vacío, el usuario ve una página en blanco hasta que el código de JavaScript de la aplicación se cargue y ejecute:

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

¡Esto puede sentirse muy lento! Para resolverlo, puedes generar el HTML inicial a partir de tus componentes en el servidor o durante la compilación. Entonces tus visitantes pueden leer el texto, ver imágenes, y hacer clic en los enlaces antes de que se cargue cualquiera de los códigos de JavaScript. Recomendamos utilizar un framework que tenga esta optimización incorporada. Dependiendo de cuando se ejecuta, se llama renderizado de lado del servidor (SSR) o generación de sitios estáticos (SSG)

Atención

Las aplicaciones que utilizan el renderizado del lado del servidor o la generación estática deben llamar a hydrateRoot en lugar de createRoot. React luego hidratará (reutilizará) los nodos del DOM de tu HTML en lugar de destruirlos y volver a crearlos.


Renderizar una página construida parcialmente con React

Si tu página no está construida completamente con React, puedes llamar a createRoot varias veces para crear una raíz para cada pieza de nivel superior de la UI administrada por React. Puedes mostrar contenido diferente en cada raíz con una llamada a root.render.

Aquí, dos componentes diferentes de React se renderizan dentro de dos nodos del DOM definidos en el archivo 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 />);

También se puede crear un nodo del DOM nuevo con document.createElement() y añadirlo al documento manualmente.

const domNode = document.createElement('div');
const root = createRoot(domNode);
root.render(<Comment />);
document.body.appendChild(domNode); // Puedes añadirlo en cualquier parte del documento

Para eliminar el árbol de React del nodo del DOM y limpiar todos los recursos utilizados por este, llama a root.unmount.

root.unmount();

Mayormente es útil si tus componentes de React están dentro de una aplicación escrita en otro framework.


Actualización de un componente raíz

Puedes llamar a render más de una vez en la misma raíz. Siempre que el árbol de componentes corresponda con lo que se había renderizado anteriormente, React preservará el estado. Fíjate que puedes escribir en el input, lo que significa que las actualizaciones por llamar repetidamente a render cada segundo en este ejemplo no son destructivas:

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);

No es común llamar a render más de una vez. En cambio, se suele actualizar el estado dentro de uno de los componentes.

Show a dialog for uncaught errors

Canary

onUncaughtError is only available in the latest React Canary release.

By default, React will log all uncaught errors to the console. To implement your own error reporting, you can provide the optional onUncaughtError root option:

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

const root = createRoot(
document.getElementById('root'),
{
onUncaughtError: (error, errorInfo) => {
console.error(
'Uncaught error',
error,
errorInfo.componentStack
);
}
}
);
root.render(<App />);

The onUncaughtError option is a function called with two arguments:

  1. The error that was thrown.
  2. An errorInfo object that contains the componentStack of the error.

You can use the onUncaughtError root option to display error dialogs:

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 />);

Displaying Error Boundary errors

Canary

onCaughtError is only available in the latest React Canary release.

By default, React will log all errors caught by an Error Boundary to console.error. To override this behavior, you can provide the optional onCaughtError root option to handle errors caught by an Error Boundary:

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

const root = createRoot(
document.getElementById('root'),
{
onCaughtError: (error, errorInfo) => {
console.error(
'Caught error',
error,
errorInfo.componentStack
);
}
}
);
root.render(<App />);

The onCaughtError option is a function called with two arguments:

  1. The error that was caught by the boundary.
  2. An errorInfo object that contains the componentStack of the error.

You can use the onCaughtError root option to display error dialogs or filter known errors from logging:

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 />);

Displaying a dialog for recoverable errors

React may automatically render a component a second time to attempt to recover from an error thrown in render. If successful, React will log a recoverable error to the console to notify the developer. To override this behavior, you can provide the optional onRecoverableError root option:

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

const root = createRoot(
document.getElementById('root'),
{
onRecoverableError: (error, errorInfo) => {
console.error(
'Recoverable error',
error,
error.cause,
errorInfo.componentStack,
);
}
}
);
root.render(<App />);

The onRecoverableError option is a function called with two arguments:

  1. The error that React throws. Some errors may include the original cause as error.cause.
  2. An errorInfo object that contains the componentStack of the error.

You can use the onRecoverableError root option to display error dialogs:

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 />);


Solución de problemas

He creado una raíz, pero no se muestra nada

Asegúrate de no haber olvidado renderizar realmente tu aplicación dentro de la raíz:

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

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

Hasta que no hagas eso, no se muestra nada.


I’m getting an error: «You passed a second argument to root.render»

A common mistake is to pass the options for createRoot to root.render(...):

Console
Warning: You passed a second argument to root.render(…) but it only accepts one argument.

To fix, pass the root options to createRoot(...), not root.render(...):

// 🚩 Wrong: root.render only takes one argument.
root.render(App, {onUncaughtError});

// ✅ Correct: pass options to createRoot.
const root = createRoot(container, {onUncaughtError});
root.render(<App />);

Recibo un error: «Target container is not a DOM element»

Este error significa que lo que esté pasando a createRoot no es un nodo del DOM.

Si no estás seguro de lo que está pasando, intenta imprimirlo en consola:

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

Por ejemplo, si domNode es null, significa que getElementById devolvió null. Esto pasa si no hay ningún nodo en el documento con el ID dado en el momento de su llamada. Puede haber algunas razones para ello:

  1. El ID que estás buscando puede diferir del ID que usaste en el archivo HTML. ¡Comprueba si hay errores tipográficos!
  2. La etiqueta <script> de tu paquete no puede «ver» ningún nodo del DOM que aparezca después de ella en el HTML.

Otra forma común de obtener este error es escribir createRoot(<App />) en lugar de createRoot(domNode).


Recibo un error: «Functions are not valid as a React child.»

Este error significa que lo que pases a root.render no es un componente de React.

Esto puede ocurrir si llamas a root.render con Component en lugar de <Component />:

// 🚩 Incorrecto: App es una función, no un componente.
root.render(App);

// ✅ Correcto: <App /> es un componente.
root.render(<App />);

O si pasas una función a root.render, en lugar del resultado de llamarla:

// 🚩 Incorrecto: createApp es una función, no un componente.

// ✅ Correcto: llama a createApp para devolver un componente.
root.render(createApp());

Mi HTML renderizado en el servidor se recrea desde cero

Si tu aplicación está renderizada en el servidor e incluye el HTML inicial generado por React, puedes notar que crear una raíz y llamar a root.render elimina todo ese HTML, y luego recrea todos los nodos del DOM desde cero. Esto puede ser más lento, reinicia el foco y las posiciones de desplazamiento y puede perder otras entradas del usuario.

Las aplicaciones renderizadas por el servidor deben usar hydrateRoot en lugar de createRoot:

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

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

Ten en cuenta que su API es diferente. En particular, usualmente no habrá una llamada posterior a root.render.