React Portals. Una introducción
Cómo emplear los React Portals para saltarte algunas de las restricciones que impone el DOM
Hace poco estuve trabajando en una aplicación que empleaba los React Portals y me pareció una característica muy interesante que nos ofrece React para permitirnos de forma nativa renderear componentes en un nodo del DOM que existen por fuera de la jerarquía del componente padre.
Dicho de otro modo, los React Portals son una API que nos permite renderear componentes “saltándonos” la jerarquía del DOM. Según la documentación oficial los portales resultan útiles cuando un componente padre tiene una propiedad del estilo z-index o overflow: hidden pero su hijo tiene que “romper” el contenedor, como por ejemplo en el caso de los tooltips, ventanas modales o menús flotantes.
Puesto que de primeras todo esto puede sonar bastante abstracto voy a mostraros dos casos de uso para que podáis ver su funcionamiento y que así entenderlos os resulte más sencillo.
¡Vamos a ello!
Creando una ventana modal con React Portals
El primer caso va a ser bastante sencillo y es el más típico a la hora de entender la manera en que funcionan los React Portals. Lo que haremos será desarrollar una aplicación muy sencilla que nos permita mostrar una ventana modal pulsando un botón.
Para ello, partiremos de un proyecto creado desde cero mediante la herramienta npx .
Lo primero que haremos será añadir a nuestro archivo index.html el elemento que contendrá a las ventanas modales de nuestra habitación y hacia el que posteriormente crearemos el portal:

Como veis, el elemento modalContainer se encuentra al mismo nivel que el elemento root (que es por otro lado donde se montará nuestra aplicación). La magia de los React Portals nos permitirá renderear componentes en el elemento del DOM modalContainer saltándonos la jerarquía de componentes de React que creemos en nuestra aplicación.
Para ello, el siguiente paso será crear nuestro componente Modal , que tendrá el siguiente aspecto:

Este componente recibe 4 propiedades pero lo que realmente nos interesa es que es aquí donde aparece el uso de ReactDOM.createPortal . Esta función recibe dos argumentos:
- La estructura a renderear como si del propio retorno de un componente funcional (o del método
renderen un componente de clase) se tratase. - El elemento del DOM donde queremos renderearlo. Es por ello que en la línea 5 estamos recurriendo a la función
document.querySelectorpara seleccionar nuestro<div id="modalContainer"></div>que añadimos en el archivoindex.html.
Hecho esto, tan sólo quedará añadir nuestro componente dentro del archivo App.js y la “magia” de los React Portals hará el resto:

Lo realmente interesante es que a nivel de React la estructura de componentes es la que vemos representada en nuestros archivos. Sin embargo, al hacer click sobre el botón Open Modal la estructura del DOM que obtenemos es la siguiente:

Repositorio
En el caso de que queráis ver en más detalle el código podéis ver el siguiente repositorio:
Propagación de eventos
Otra de las cosas curiosas al trabajar con los React Portals es la forma en que se propagan los eventos, ya que aunque el contenido del portal se pinte en otra parte del DOM el componente a nivel interno se sigue comportando como si de un hijo del componente padre se tratase.
Dicho de otro modo y tomando como referencia las palabras de la propia documentación de React:
Un evento activado desde adentro de un portal se propagará a los ancestros en el árbol de React, incluso si esos elementos no son ancestros en el árbol DOM.
Veámoslo modificando un poco el ejemplo anterior:

El componente <Child> , que pintamos dentro de nuestro componente Modal posee un botón capaz de recibir clicks (línea 6) pero, además, hemos añadido un onClick en la línea 17 de modo que cada click dentro del componente App se incremente el contador.
Lo interesante es que, pese a que hagamos click en el botón pintado dentro de la modal (el cual es pintado en el elemento del DOM modalContainer ), el componente App sigue recibiendo los clicks puesto que React mantiene la jerarquía de los componentes.






