DEV Community

Francisco Villarreal
Francisco Villarreal

Posted on

Como manejar modales con hooks en react

En este artículo, exploraremos cómo crear un ModalProvider para controlar los modales utilizados en una aplicación desde cualquier punto de la misma. Esta implementación nos ayudará a gestionar los modales con mayor facilidad y coherencia en toda la aplicación.

Todo el código que vamos a presentar se puede encontrar en el siguiente repositorio.

Creación del Hook useModal

Lo primero en lo que nos centraremos es en la creación de un hook que mantendrá el estado de los modales abiertos.

import { useState } from 'react';
import { modalStore } from '../providers/modalProvider';

export default function useModal(){
  const [modalList, setModalList]= useState<modalStore[]>([])
  
  const openModal = (newModal: modalStore)=> {
    setModalList(old=> [...old, newModal])
  }
  const closeModal =(id: number)=> {
    setModalList(old=> old.filter(modal=> modal.id != id))
  }
  
  return {modalList, openModal, closeModal}
}
Enter fullscreen mode Exit fullscreen mode

la función de este hook va estar enfocada en mantener la información y poder modificarlo atreves de los dos métodos

Este hook se centra en mantener la información sobre los modales abiertos y permite su modificación a través de dos métodos:

  • openModal(newModal: ModalStore): Este método añade un nuevo modal a la lista de modales abiertos.
  • closeModal(id: number): Este método cierra el modal correspondiente al ID proporcionado.

Uso del ModalProvider

Ahora, vamos a implementar el ModalProvider, que utilizará el hook useModal para proporcionar el control de modales en toda la aplicación.

import { ReactNode, createContext } from 'react';
import ModalController from '../components/modalControler';
import useModal from '../hook/useModal';

export enum ModalType {
  "helloModal",
  "byeModal",
}

export interface modalStore {
  id: number;
  type: ModalType | null;
  data?: unknown;
}

interface contextModalInterface{
  modalList: modalStore[],
  openModal: (type: modalStore) => void
  closeModal: (id: number) => void
}

export const ModalContext = createContext<contextModalInterface>({
    modalList: [],
    openModal: () => {},
    closeModal: () => {},
});

export const ModalProvider = ({children}: {children: ReactNode})=> {
  const {modalList, openModal, closeModal} = useModal()
  return (
    <ModalContext.Provider value={{modalList, openModal, closeModal}}>
      
      {children}
    </ModalContext.Provider>
  )
}
Enter fullscreen mode Exit fullscreen mode

controlador de modales

una ves creado el Provider tenemos que crear otro componente el que va estar encargado de desplegar los modales que se desean utilizar va ser de la siguiente forma

import { useContext } from "react";
import {
  ModalContext,
  ModalType,
  modalStore,
} from "../providers/modalProvider";
import HelloModal from "./helloModal";
import ByeModal from "./byeModal";  

export default function ModalController() {
  const { modalList } = useContext(ModalContext);
  return (
    <>
      {modalList.map(({ type, data, id }: modalStore) =>
        type === ModalType.helloModal ? (
          <HelloModal data={data as string} key={id} id={id} />
        ) : type === ModalType.byeModal ? (
          <ByeModal key={id} id={id} />
        ) : null
      )}
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

la tarea principal de este componente es la de iterar todos la lista de todos los modales que se desean visualizar

después de crear este componente lo tenemos que mandar llamar y este va estar alojado dentro de componente ModalProvider que anterior mente creamos

export const ModalProvider = ({children}: {children: ReactNode})=> {
  const {modalList, openModal, closeModal} = useModal()
  return (
    <ModalContext.Provider value={{modalList, openModal, closeModal}}>
      <ModalController/>
      {children}
    </ModalContext.Provider>
  )
}
Enter fullscreen mode Exit fullscreen mode

y por ultimo tenemos que hacer uso del componente modalProvider que creamos y este va ir situado en la mas alta del la estructura de la aplicación para que tengamos acceso a al contexto atreves de toda la aplicación

import "./App.css";
import { ModalProvider } from "./providers/modalProvider";
import Dashboard from "./components/dashboard";
function App() {
  return (
    <div className="relative">
      <ModalProvider>
        <Dashboard />
      </ModalProvider>
    </div>
    
  );
}
export default App;
Enter fullscreen mode Exit fullscreen mode

una ves creado todos los elementos requeridos para esta implementación solo falta mandar llamar un modal que esto se haría de la siguiente manera

import { useContext } from "react";
import { ModalContext, ModalType } from "../providers/modalProvider";

export default function Dashboard() {
  const { openModal, modalList } = useContext(ModalContext);
  return (
    <>
      <button
        onClick={() =>
          openModal({
            id:modalList.length + 1,
            type: ModalType.helloModal,
            data: "francisco",
          })
        }
      >
        open Hello Modal
      </button>
      <button
        onClick={() =>
          openModal({
            id: modalList.length + 1,
            type: ModalType.byeModal,
            data: "francisco",
          })
        }
      >
        open Bye Modal
      </button>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Conclusión

En este artículo, hemos explorado cómo mejorar el control de modales en una aplicación React mediante la creación de un ModalProvider. Esta implementación nos permite gestionar los modales de manera centralizada y eficiente desde cualquier punto de la aplicación.

Al utilizar un hook personalizado llamado useModal, hemos encapsulado la lógica para mantener el estado de los modales abiertos y proporcionar métodos para abrir y cerrar modales. Esto nos permite mantener un código más limpio y modular, ya que toda la lógica relacionada con los modales se encuentra en un único lugar.

Además, al utilizar el contexto de React, hemos creado un ModalProvider que proporciona el estado y los métodos necesarios para el control de modales a todos los componentes hijos. Esto facilita el acceso y la gestión de los modales en cualquier parte de la aplicación.

Al final, hemos integrado el ModalProvider en nuestra aplicación principal, lo que nos permite mejorar la experiencia del usuario al tener un control más consistente y coherente de los modales.

Top comments (0)