Поиск по сайту:

4 шага для настройки глобальных модальных окон в React


Узнайте, как создавать интерактивные всплывающие окна в веб-приложении React.

Модальный диалог — это окно, которое появляется поверх веб-страницы и требует взаимодействия с пользователем, прежде чем оно исчезнет. В React есть несколько способов помочь вам создавать модальные окна и управлять ими с минимальным написанием кода.

Если вы создаете их в локальной области, вам необходимо импортировать модальные окна в каждый компонент, а затем создать состояние для управления статусом открытия и закрытия каждого модального окна.

Используя глобальное состояние, вам не нужно импортировать модальные окна в каждый компонент или создавать состояние для каждого. Вы можете импортировать все модальные окна в одном месте и использовать их где угодно.

По моему мнению, лучший способ управлять модальными диалогами в вашем приложении React — глобально, используя контекст React, а не локальное состояние.

Как создать глобальные модальные окна

Вот шаги (и код) для настройки глобальных модальных окон в React. В качестве основы я использую Patternfly, но его принципы применимы к любому проекту.

1. Создайте глобальный модальный компонент.

В файле GlobalModal.tsx создайте модальное определение:

import React, { useState, createContext, useContext } from 'react';
import { CreateModal, DeleteModal,UpdateModal } from './components';

export const MODAL_TYPES = {
CREATE_MODAL:”CREATE_MODAL”,
 DELETE_MODAL: “DELETE_MODAL”,
 UPDATE_MODAL: “UPDATE_MODAL”
};

const MODAL_COMPONENTS: any = {
 [MODAL_TYPES.CREATE_MODAL]: CreateModal,
 [MODAL_TYPES.DELETE_MODAL]: DeleteModal,
 [MODAL_TYPES.UPDATE_MODAL]: UpdateModal
};

type GlobalModalContext = {
 showModal: (modalType: string, modalProps?: any) => void;
 hideModal: () => void;
 store: any;
};

const initalState: GlobalModalContext = {
 showModal: () => {},
 hideModal: () => {},
 store: {},
};

const GlobalModalContext = createContext(initalState);
export const useGlobalModalContext = () => useContext(GlobalModalContext);

export const GlobalModal: React.FC<{}> = ({ children }) => {
 const [store, setStore] = useState();
 const { modalType, modalProps } = store || {};

 const showModal = (modalType: string, modalProps: any = {}) => {
   setStore({
     ...store,
     modalType,
     modalProps,
   });
 };

 const hideModal = () => {
   setStore({
     ...store,
     modalType: null,
     modalProps: {},
   });
 };

 const renderComponent = () => {
   const ModalComponent = MODAL_COMPONENTS[modalType];
   if (!modalType || !ModalComponent) {
     return null;
   }
   return <ModalComponent id="global-modal" {...modalProps} />;
 };

 return (
   <GlobalModalContext.Provider value={{ store, showModal, hideModal }}>
     {renderComponent()}
     {children}
   </GlobalModalContext.Provider>
 );
};

В этом коде все компоненты диалога сопоставлены с модальным типом. Функции showModal и hideModal используются для открытия и закрытия диалоговых окон соответственно.

Функция showModal принимает два параметра: modalType и modalProps. Параметр modalProps является необязательным; он используется для передачи любого типа данных модальному модулю в качестве реквизита.

Функция hideModal не имеет параметров; его вызов приводит к закрытию текущего открытого модального окна.

2. Создайте компоненты модального диалога.

В файле CreateModal.tsx создайте модальное окно:

import React from "react";
import { Modal, ModalVariant, Button } from "@patternfly/react-core";
import { useGlobalModalContext } from "../GlobalModal";

export const CreateModal = () => {
 const { hideModal, store } = useGlobalModalContext();
 const { modalProps } = store || {};
 const { title, confirmBtn } = modalProps || {};

 const handleModalToggle = () => {
   hideModal();
 };

 return (
   <Modal
     variant={ModalVariant.medium}
     title={title || "Create Modal"}
     isOpen={true}
     onClose={handleModalToggle}
     actions={[
       <Button key="confirm" variant="primary" onClick={handleModalToggle}>
         {confirmBtn || "Confirm button"}
       </Button>,
       <Button key="cancel" variant="link" onClick={handleModalToggle}>
         Cancel
       </Button>
     ]}
   >
     Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
     tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
     veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
     commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
     velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
     cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
     est laborum.
   </Modal>
 );
};

Здесь есть специальный крючок useGlobalModalContext, который предоставляет объект хранилища, откуда вы можете получить доступ ко всем реквизитам и функциям showModal и hideModal. Вы можете закрыть модальное окно с помощью функции hideModal.

Чтобы удалить модальное окно, создайте файл с именем DeleteModal.tsx:

import React from "react";
import { Modal, ModalVariant, Button } from "@patternfly/react-core";
import { useGlobalModalContext } from "../GlobalModal";

export const DeleteModal = () => {
 const { hideModal } = useGlobalModalContext();

 const handleModalToggle = () => {
   hideModal();
 };

 return (
   <Modal
     variant={ModalVariant.medium}
     title="Delete Modal"
     isOpen={true}
     onClose={handleModalToggle}
     actions={[
       <Button key="confirm" variant="primary" onClick={handleModalToggle}>
         Confirm
       </Button>,
       <Button key="cancel" variant="link" onClick={handleModalToggle}>
         Cancel
       </Button>
     ]}
   >
     Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
     tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
     veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
     commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
     velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
     cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
     est laborum.
   </Modal>
 );
};

Чтобы обновить модальное окно, создайте файл с именем UpdateModal.tsx и добавьте этот код:

import React from "react";
import { Modal, ModalVariant, Button } from "@patternfly/react-core";
import { useGlobalModalContext } from "../GlobalModal";

export const UpdateModal = () => {
 const { hideModal } = useGlobalModalContext();

 const handleModalToggle = () => {
   hideModal();
 };

 return (
   <Modal
     variant={ModalVariant.medium}
     title="Update Modal"
     isOpen={true}
     onClose={handleModalToggle}
     actions={[
       <Button key="confirm" variant="primary" onClick={handleModalToggle}>
         Confirm
       </Button>,
       <Button key="cancel" variant="link" onClick={handleModalToggle}>
         Cancel
       </Button>
     ]}
   >
     Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
     tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
     veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
     commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
     velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
     cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
     est laborum.
   </Modal>
 );
};

3. Интегрируйте GlobalModal в компонент верхнего уровня вашего приложения.

Чтобы интегрировать новую модальную структуру, которую вы создали, в свое приложение, вы просто импортируете созданный вами глобальный модальный класс. Вот мой пример файла App.tsx :

import "@patternfly/react-core/dist/styles/base.css";
import "./fonts.css";
import { GlobalModal } from "./components/GlobalModal";
import { AppLayout } from "./AppLayout";

export default function App() {
 return (
   <GlobalModal>
     <AppLayout />
   </GlobalModal>
 );
}

App.tsx — это компонент верхнего уровня вашего приложения, но вы можете добавить еще один компонент в соответствии со структурой вашего приложения. Однако убедитесь, что это один уровень выше того места, где вы хотите получить доступ к модальным окнам.

GlobalModal — это компонент корневого уровня, в который все ваши модальные компоненты импортируются и сопоставляются с их конкретным modalType.

4. Выберите кнопку модального окна в компоненте AppLayout.

Добавление кнопки в модальное окно с помощью AppLayout.js:

import React from "react";
import { Button, ButtonVariant } from "@patternfly/react-core";
import { useGlobalModalContext, MODAL_TYPES } from "./components/GlobalModal";

export const AppLayout = () => {
 const { showModal } = useGlobalModalContext();

 const createModal = () => {
   showModal(MODAL_TYPES.CREATE_MODAL, {
     title: "Create instance form",
     confirmBtn: "Save"
   });
 };

 const deleteModal = () => {
   showModal(MODAL_TYPES.DELETE_MODAL);
 };

 const updateModal = () => {
   showModal(MODAL_TYPES.UPDATE_MODAL);
 };

 return (
   <>
     <Button variant={ButtonVariant.primary} onClick={createModal}>
       Create Modal
     </Button>
     <br />
     <br />
     <Button variant={ButtonVariant.primary} onClick={deleteModal}>
       Delete Modal
     </Button>
     <br />
     <br />
     <Button variant={ButtonVariant.primary} onClick={updateModal}>
       Update Modal
     </Button>
   </>
 );
};

В компоненте AppLayout есть три кнопки: создать модальное окно, удалить модальное окно и обновить модальное окно. Каждое модальное окно сопоставляется с соответствующим modalType: CREATE_MODAL, DELETE_MODAL или UPDATE_MODAL.

Используйте глобальные диалоги

Глобальные модальные окна — это чистый и эффективный способ обработки диалогов в React. Их также легче поддерживать в долгосрочной перспективе. В следующий раз, когда вы будете создавать проект, помните об этих советах.

Если вы хотите увидеть код в действии, я поместил полное приложение, созданное для этой статьи, в песочницу.

Статьи по данной тематике: