createRoot
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?)
Uso
Renderizar una app construida completamente con React
Si tu app está construida completamente con React, crea una raíz única para tu app entera.
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:
- Encontrará el nodo del DOM del navegador definido en tu HTML.
- Mostrará el componente de React para tu app.
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 app 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 app entera. Para agregar más componentes, anídelos dentro del componente de la App
. Cuando necesitas actualizar la interfaz del usuario (UI), cada uno de tus componentes puede lograr por usar el estado. Cuando necesitas mostrar contenido adicional como un modal o herramientas de ayuda fuera del nodo del DOM, renderizar con un portal.
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 del interfaz de usuario (UI) administrada por React. Puede mostrar contenido diferente en cada raíz por llamar a root.render
.
Aquí, dos componentes diferentes de React se renderizan a 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 por cualquier parte del documento
Para quitar el árbol de React del nodo del DOM y limpiar todos los recursos utilizados por él, llama a root.unmount
.
root.unmount();
Mayormente es útil si tus componentes de React están dentro de una app 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. Ten en cuenta que se puede escribir en el input que significa que las actualizaciones por llamar a render
cada segundo en este ejemplo no son destructivos:
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 render
más de una vez. En cambio, se suele actualizar el estado dentro de uno de los componentes.
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.
const domNode = document.getElementById('root');
const root = createRoot(domNode);
React creará una raíz para el domNode
y tomará el control sobre manejar el 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 app 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.
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, comorender
y mostrar el contenido renderizado por React. -
opcional
opciones
: Un objeto contiene opciones para esta raíz React.onRecoverableError
: callback opcional llamado cuando React se recupera de errores automáticamente.identifierPrefix
: prefijo opcional que React utiliza para IDs generados poruseId
. Útil para evitar conflictos cuando se utiliza raíces varias en la misma página.
Retornos
createRoot
retorna un objeto con dos métodos: render
y unmount
.
Advertencias
- Si tu app se renderiza por el servidor, usar
createRoot()
no es soportado. En cambio, utilizahydrateRoot()
. - Probablemente, solo se llamará
createRoot
una vez en tu app. Si se utiliza un framework, puede que se haga 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 una herramienta de ayuda), ocupa
createPortal
en vez decreateRoot
.
root.render(reactNode)
Llama root.render
para mostrar una pieza de JSX (“React node”) en el nodo del DOM del navegador de la raíz de React.
root.render(<App />);
React mostrará <App />
en la root
y se encargará de administrar el DOM dentro de él.
Parámetros
reactNode
: Un Nodo de React que desea mostrar. Por lo general, será una pieza de JSX como<App />
, pero también puedes pasar un elemento de React construido concreateElement()
, una string, un número,null
, oundefined
.
Retornos
root.render
devuelve undefined
.
Advertencias
-
La primera vez que tú llamas a
root.render
, React borrará todo el contenido HTML existente dentro de la raíz de React antes de representar el componente de React en él. -
Si el nodo del DOM de su raíz contiene HTML generado por React en el servidor o durante la compilación , usa
hydrateRoot()
en cambio, que adjunta los controladores de eventos al HTML existente. -
Si tú 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 pasó. React decidirá qué partes del DOM se pueden reutilizar y cuáles deben ser recreadas por “emparejarlo” con el árbol renderizado previamente. Llamar arender
en la misma raíz nuevamente es similar a llamar a la funcionset
en el componente de 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 app completamente construida con React usualmente no tendrá ninguna llamada a root.unmount
.
Esto es principalmente útil si el nodo del DOM de su raiz de React (o cualquiera de sus ancestros) puede ser eliminado del DOM por algún otro código. Por ejemplo, imagine 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, debe decirle a React que “detenga” la administración del contenido de la raíz eliminada por llamar 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 de la raíz del nodo del DOM, incluida la eliminación de cualquier controlador de eventos o estado en el árbol.
Parámetros
root.unmount
no acepta ningún parámetro.
Retornos
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 llame a
root.unmount
, no podrá volver a llamar aroot.render
en la misma raíz. Intentar llamar aroot.render
en una raíz desmontada generará el error “No se puede actualizar una raíz desmontada”. Sin embargo, puede crear una nueva raíz para el mismo nodo DOM después de que se haya desmontado la raíz anterior para ese nodo.
Solución de problemas
He creado una raíz, pero no se muestra nada
Asegúrate de no haber olvidado realmente renderizar tu app en 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 registrarlo:
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 la ID dado en el momento de su llamada. Puede haber algunas razones para ello:
- El ID que está buscando puede diferir del ID que usaste en el archivo HTML. ¡Comprueba si hay errores tipográficos!
- La etiqueta
<script>
de su paquete no puede “ver” ningún nodo del DOM que aparezca after de él en el HTML.
Si no puedes hacerlo funcionar, consulta Adding React to a Website para ver un ejemplo que sirve.
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 occurrir 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 llamarle:
// 🚩 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 Agregando React a un sitio web para un ejemplo que funciona.
Mi HTML renderizado por el servidor se recrea desde cero
Si tú app está renderizada por 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 recrear todos los nodos del DOM desde cero. Esto puede ser más lento, restablece el enfoque y las posiciones de desplazamiento y puede perder otras entradas del usuario.
Rutas 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 tu API es diferente. En particular, usualmente no llamará a root. render
.