模态对话框是一个出现在网页顶部的窗口,需要用户交互后才会消失。 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 中处理对话框的一种简洁有效的方式。 从长远来看,它们也更容易维护。 下次设置项目时,请记住这些提示。
如果您想查看代码的实际效果,我已将我为本文创建的完整应用程序包含在沙箱中。
评论已关闭。