Cómo renderizar modales en React

Los modales pueden ser un tema complicado en React debido a la forma en que React estructura el DOM. Si está familiarizado con los conceptos básicos de React, sabrá que toda la aplicación es un componente, generalmente llamado que se agrega como un niño llamado #root. El archivo index.html se ve así:

Una vez que el componente se procesa en el DOM, el elemento real con la identificación "#root" obtiene la aplicación React completa en su interior.

En consecuencia, es bastante común que los componentes de la aplicación React se aniden muy profundamente. Estamos hablando de decenas de niveles de profundidad y, a menudo, más. Entonces, si uno de esos Componentes profundamente anidados necesita mostrar un modal, enfrentará algunos problemas serios de CSS.

Los modales colocan una superposición en la pantalla y, por lo tanto, tienen una mayor prioridad visual sobre todos los demás elementos. Si tuviera que ponerlo en términos de índice Z, tendría que ser el número más alto de todos los elementos en pantalla. Pero dado que está tan profundamente anidado, los elementos principales en el árbol tienen prioridad de CSS.

En lugar de tocar el CSS, que puede estar finamente ajustado, por lo que tocar el violín podría romper la aplicación, necesitamos encontrar una manera de renderizar al DOM, pero fuera del anidamiento profundo .

Solución: portales de React

Una estrategia es usar portales ReactDOM y poner el modal en un div que sea un componente hermano del div con id "#root". Al hacerlo, los estilos CSS aplicados al contenedor div del modal se aplicarán solo en relación con su hermano (el div "#root"), y eso no romperá el estilo CSS de "#root".

Para hacerlo, necesitamos usar el createPortal()método de ReactDOM. Un portal es efectivamente un div hermano, que dobla la regla de que todos los componentes de React deben ser descendientes de . Para hacerlo, debemos hacer lo siguiente:

  1. En index.html, dentro de la etiqueta: y>
  You need to enable JavaScript to run this app. . //ADD THIS  

2. Cree un componente Modal.js (los classNames son de semantic-UI ):

import React from "react"; import ReactDOM from "react-dom"; const JSX_MODAL = ( THIS IS SOME TEXT IN THE MODAL // add some UI features here ); function Modal(props) { return ReactDOM.createPortal(JSX_MODAL, document.querySelector("#modal")); } export default Modal;

Verá que createPortaltoma dos argumentos: algo de JSX que se renderiza y similar al ReactDOM.renderelemento de destino bajo el cual se renderiza JSX.

Si renderiza el Componente y navega hasta él, debería encontrar que se muestra bastante bien. Ahora necesita agregar el onClick() controlador apropiado para manejar eventos de clic dentro de la IU modal interna, así como para navegar fuera de la modalidad si el usuario hace clic fuera de la IU modal interna.

Querrá hacer esto escuchando los clics en el área correcta y luego deteniendo la propagación para que surjan los comportamientos correctos según la región donde el usuario hace clic.

Reutilización

El ejemplo anterior es extremadamente básico y no pretende ser un fragmento de código listo para usar. Más bien, esta es una solución para abordar los modales. Debe personalizar absolutamente el componente de acuerdo con sus necesidades. Utilice los principios de reutilización de React para asegurarse de que no está codificando datos de forma rígida en el modal y transmita el contenido e incluso los widgets más pequeños según sea necesario.

Por ejemplo, en uno de mis proyectos, presento un modal cuando el usuario va a eliminar algo de la base de datos. Entonces mi componente se llama, digamos . Se renderiza , que es la superposición que atenúa la pantalla subyacente .

render() { return ( ); } renderActionButtons = () => { //return JSX that renders action buttons... return ( Delete Cancel ); };

Dentro /> is an inner component c alled rModal /> and this has the actual interactive component, with headers, content and text.

So my /> component creates props to pass down into <;Modal /> which in turn gets drille d down into <;InnerModal />, and so the render method in looks like:

…with the actual Modal Component looking like:

import React from "react"; import ReactDOM from "react-dom"; import ModalInner from './modal-inner' function Modal(props) { return ReactDOM .createPortal( , document.querySelector("#modal") //target DOM element ); } export default Modal;

and now, you’re finally able to render:

Voilà, there you have it! Modals, with React Portal! Hope you enjoyed this ?

And hope it saved you some ? ? ?…

If you would like to talk about your journey, I would love to listen. Tweet me @ZubinPratap. If you think what you just read could be useful to someone, please share it.

[Update] Quincy at FreeCodeCamp has relaunched the FreeCodeCamp podcast, and uses his incredible experience as an educator to pull together content that will help you on your journey. I was recently on episode 53 and if you’re new to development, you should check it out to see how many people are like us, and how much is possible for us! You can also access the podcast on iTunes, Stitcher, and Spotify or directly from this page.

Follow my Medium blog , my Github page and, if you’re so inclined, hit me up on LinkedIn.

Founder at Whooshka.me