¿Qué son los React Portals?

Portals es una Api de React que nos permite renderizar cualquier componente o código html fuera de nuestro árbol de componentes Dom (por defecto <div id=”root”>  dentro de index.html).

Para hacernos una idea, un portal sería como un agujero de gusano donde en un nodo tendríamos un <div id=»otroDiv»> aislado en index.html y en otro nodo tendríamos un trozo de código html o un componente declarado en otro <div id=»root»> . Este componente usaría métodos en el componente donde lo declaramos, pero a la hora de ser pintado, pasa por el portal y se pinta en <div id=»otroDiv»> .

¿En qué nos puede ayudar?

Normalmente, los componentes en React siguen una jerarquía padre-hijo, donde un componente puede renderizar otro, este a su vez otro, etc… Nuestro problema viene cuando queremos crear un elemento fuera de toda esta jerarquía, y que no se vea afectado por el estilo css (concretamente, por la propiedad z-index u overflow) del componente padre

Usando portal para mostrar un Modal (ventana popup)

Ahora que conocemos los portals podemos seguir los siguientes pasos para crear un componente que sea nuestra ventana Modal, declararlo en cualquier componente de nuestra app y que se pinte fuera de nuestra jerarquía root.

Para ello, en un proyecto cualquiera, lo primero que haremos será ir a index.html y añadir un nuevo div:

7

Una vez hecho esto, vamos a crear un nuevo componente que enlazaremos a este nuevo div. Lo llamaremos Portal.js

6

Importamos reactDOM, creamos una constante para enlazar al div con document.getElementById(‘portal’) y en el render solo vamos a devolver el  método createPortal() de ReactDOM pasándole como parámetros los propios elementos hijos que rendericemos al crear un <Portal></Portal> y como segundo, un nuevo div que creemos. (nuevoDiv)

Teniendo nuestro portal, podemos crear ya nuestro Modal.js, que será nuestra propia ventana.

5

En Modal.js importamos Portal para meterlo dentro del return, ya que, como hemos dicho antes, lo que se renderizará en el nuevo div serán los elementos hijos de <Portal>. Con lo cual, dentro de este meteremos un div que será toda la pantalla del navegador, y dentro meteremos otro div que será el propio popup y a su nivel, otro div que será el fondo negro. Dentro del div ventana meteremos el botón de cerrar y recibiremos por props el código html que introduzcamos dentro de <Modal></Modal> (children) que será el contenido personalizado de nuestra ventana (una imagen, un texto…).

Una vez hecho esto añadimos algunos estilos para dar forma a la ventana y poner el background negro. En este ejemplo, los pondré en una constante que llamaré styles.

4

Con los estilos ya creados, podemos ir a cualquier componente donde queramos controlar el modal (En este caso, en AppComponent) y en el render devolvemos el Modal.

3

Dentro de modal crearemos los elementos children mencionados anteriormente (un text, foto, etc…). Teniendo el modal en AppComponent, vamos a meter en el render un botón que active el modal. Luego crearemos una variable de state que llamaremos activo que se encargará de control si el modal se muestra o no, y un método que llamaremos toggle para cambiar dicha variable state. Tanto el método como la variable se la pasaremos al Modal por props, y añadiremos al botón creado anteriormente un onClick del metodo toggle, quedando nuestro componente AppComponent así:

2 actualizado

Con esto lograremos que el metodo toggle esté enlazado al modal, independientemente de si éste se renderiza en <div id=»portal»> y no en <div id=»root»>(donde está AppComponent).

Por último, en el Modal recogemos esos props (toggle y state.activo) y ponemos una condición: Si activo es true, mostraremos todo el div modal. Aparte, pondremos en el botón cerrar del modal y en el fondo negro un onClick con el método toggle. Así al pulsar fuera de la ventana o en la X se cerrará la ventana cambiando la variable state.activo. De esta forma, Modal.js quedaría así:

1

Con todo esto, podemos comprobar al arrancar nuestro proyecto que al pulsar en el botón se crea el Modal en un div distinto y al pulsar en la X de la ventana o en el fondo oscuro se cierra y el contenido de <div id=»portal»> desaparece.

modal

Conclusión

Portal es una API muy útil, y se puede adaptar a otros contextos, como enlazar eventos entre dos componentes renderizados en distintas ventanas del navegador, crear tooltips, menús flotantes…

Autor/a: Raúl Castro de la Torre

Curso: Desarrollo Web Full Stack, MultiCloud y Multiplataforma

Centro: Tajamar

Año académico: 2020-2021

Otros datos de interés:

Enlace a GitHub: https://github.com/karba98/Tajamar-Wordpress.git

LinkedIn: https://www.linkedin.com/in/raul-castro-de-la-torre-861508103

Leave a Comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.