在 React 中设置全局模态框的 4 个步骤

了解如何在 React Web 应用程序中创建交互式弹出窗口。
66 位读者喜欢这篇文章。
Digital creative of a browser on the internet

模态对话框是一个出现在网页顶部的窗口,需要用户交互后才会消失。 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>
 );
};

在此代码中,所有对话框组件都映射到模态框类型。 showModalhideModal 函数用于打开和关闭对话框。

showModal 函数有两个参数:modalTypemodalPropsmodalProps 参数是可选的;它用于将任何类型的数据作为属性传递给模态框。

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,它提供了一个存储对象,你可以从中访问所有属性以及函数 showModalhideModal。 你可以使用 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 组件中有三个按钮:创建模态框、删除模态框和更新模态框。 每个模态框都映射到相应的 modalTypeCREATE_MODALDELETE_MODALUPDATE_MODAL

使用全局对话框

全局模态框是在 React 中处理对话框的一种简洁有效的方式。 从长远来看,它们也更容易维护。 下次设置项目时,请记住这些提示。

如果您想查看代码的实际效果,我已将我为本文创建的完整应用程序包含在沙箱中。

接下来阅读什么
User profile image.
Ajay Pratap 是来自印度北方邦阿格拉的全栈开发人员。 目前在 Red Hat India 担任高级软件工程师。 他曾为 Red Hat AMQ Online 做出贡献,目前为 Red Hat Managed Kafka Services Micro Frontends 应用程序做出贡献。 一位开源爱好者和贡献者。

评论已关闭。

Creative Commons License本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.