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.

Mira m√°s ejemplos debajo.

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.

    • opcional onRecoverableError: callback que se llama cuando React se recupera de errores autom√°ticamente.
    • 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.

Mira m√°s ejemplos debajo

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 manejadores 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 manejador de eventos 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 mantendrá 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.


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.


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.

Si no puedes hacerlo funcionar, consulta A√Īadir React a un sitio web para ver un ejemplo que funciona.

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

Si no puedes hacerlo funcionar, consulte A√Īadir React a un sitio web para ver un ejemplo que funciona.


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, restablece 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.