如何在 React 中创建模态框
让我们开始编程吧
React 中最常用的组件之一无疑是模态框,因为它们可以在不同的场景中使用,从消息传递到用户输入。
与 React 中的许多其他组件一样,可以安装依赖项来帮助完成此过程,但是我们最终总会在几个方面受到限制,其中之一就是样式。
因此,我萌生了撰写本文的想法,我们将运用我们已经掌握的 CSS、属性和钩子等知识。
让我们开始编程吧
今天我们唯一要安装的就是一个图标库,以便更方便使用(不过,如果您使用网络字体,效果也一样):
npm install react-icons
现在我们可以立即开始工作了Modal.jsx。但首先让我们来谈谈 CSS。
我们将要开设的一个类就叫做.darkBG“模态框”,因为模态框打开后,我会添加一个背景色来稍微遮盖页面上的其他组件。这样做是为了让用户的注意力只集中在模态框上。
然后,我们的组件将分为三个区域,第一个区域是头部,您可以在这里放置模态框标题。第二个区域是内容,您可以在这里放置您想要的消息。
第三部分也是最后一部分将介绍可以在模态框中执行的操作,即取消模态框以将其关闭,以及其他操作(保存、更新、删除等)。
现在我们已经有了一些概念,您可以复制这段 CSS 代码(您可以自由修改它来自定义您的模态框):
/* @src/components/Modal.module.css */
.darkBG {
background-color: rgba(0, 0, 0, 0.2);
width: 100vw;
height: 100vh;
z-index: 0;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.centered {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.modal {
width: 250px;
height: 170px;
background: white;
color: white;
z-index: 10;
border-radius: 16px;
box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.04);
}
.modalHeader {
height: 50px;
background: white;
overflow: hidden;
border-top-left-radius: 16px;
border-top-right-radius: 16px;
}
.heading {
margin: 0;
padding: 10px;
color: #2c3e50;
font-weight: 500;
font-size: 18px;
text-align: center;
}
.modalContent {
padding: 10px;
font-size: 14px;
color: #2c3e50;
text-align: center;
}
.modalActions {
position: absolute;
bottom: 2px;
margin-bottom: 10px;
width: 100%;
}
.actionsContainer {
display: flex;
justify-content: space-around;
align-items: center;
}
.closeBtn {
cursor: pointer;
font-weight: 500;
padding: 4px 8px;
border-radius: 8px;
border: none;
font-size: 18px;
color: #2c3e50;
background: white;
transition: all 0.25s ease;
box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.06);
position: absolute;
right: 0;
top: 0;
align-self: flex-end;
margin-top: -7px;
margin-right: -7px;
}
.closeBtn:hover {
box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.04);
transform: translate(-4px, 4px);
}
.deleteBtn {
margin-top: 10px;
cursor: pointer;
font-weight: 500;
padding: 11px 28px;
border-radius: 12px;
font-size: 0.8rem;
border: none;
color: #fff;
background: #ff3e4e;
transition: all 0.25s ease;
}
.deleteBtn:hover {
box-shadow: 0 10px 20px -10px rgba(255, 62, 78, 0.6);
transform: translateY(-5px);
background: #ff3e4e;
}
.cancelBtn {
margin-top: 10px;
cursor: pointer;
font-weight: 500;
padding: 11px 28px;
border-radius: 12px;
font-size: 0.8rem;
border: none;
color: #2c3e50;
background: #fcfcfc;
transition: all 0.25s ease;
}
.cancelBtn:hover {
box-shadow: none;
transform: none;
background: whitesmoke;
}
如您所见,这些 CSS 类都非常简单,现在我们可以开始着手我们的工作了Modal.jsx。
// @src/components/Modal.jsx
import React from "react";
const Modal = () => {
return <h1>Hello Modal</h1>;
};
export default Modal;
我们首先要添加的内容之一就是样式,在本文中,我们将使用 CSS 模块。
// @src/components/Modal.jsx
import React from "react";
import styles from "./Modal.module.css";
const Modal = () => {
return <h1>Hello Modal</h1>;
};
export default Modal;
我们的模态框中需要一个关闭按钮,为此我们需要图标,下面我们将导入要使用的图标:
// @src/components/Modal.jsx
import React from "react";
import styles from "./Modal.module.css";
import { RiCloseLine } from "react-icons/ri";
const Modal = () => {
return <h1>Hello Modal</h1>;
};
export default Modal;
有一点需要注意的是,我们需要接收 props,以便在模态框打开后立即将其关闭。因此,我们将接收一个名为 `close` 的函数作为 props setIsOpen()。
// @src/components/Modal.jsx
import React from "react";
import styles from "./Modal.module.css";
import { RiCloseLine } from "react-icons/ri";
const Modal = ({ setIsOpen }) => {
return <h1>Hello Modal</h1>;
};
export default Modal;
完成以上步骤后,我们就可以开始制作模板了。首先,我们将添加深色背景,以便在模态框打开时更加醒目。
当用户点击深色背景时,我们希望关闭模态框,因此我们将添加onClickReact 事件并将一个布尔值作为函数的唯一参数传递setIsOpen()(在本例中为false)。
// @src/components/Modal.jsx
import React from "react";
import styles from "./Modal.module.css";
import { RiCloseLine } from "react-icons/ri";
const Modal = ({ setIsOpen }) => {
return (
<>
<div className={styles.darkBG} onClick={() => setIsOpen(false)} />
// ...
</>
);
};
export default Modal;
现在我们要开始制作模态框了,所以我们要添加一个包装器,使模态框在屏幕上居中(.centered),以及模态框的主体(.modal)和它的标题(.modalHeader)。
// @src/components/Modal.jsx
import React from "react";
import styles from "./Modal.module.css";
import { RiCloseLine } from "react-icons/ri";
const Modal = ({ setIsOpen }) => {
return (
<>
<div className={styles.darkBG} onClick={() => setIsOpen(false)} />
<div className={styles.centered}>
<div className={styles.modal}>
<div className={styles.modalHeader}>
<h5 className={styles.heading}>Dialog</h5>
</div>
// ...
</div>
</div>
</>
);
};
export default Modal;
现在我们可以添加一个按钮,其中包含用于关闭模态框的图标,该按钮还将包含一个onClick事件,并将setIsOpen()函数传递给该事件,false以便在单击此按钮时立即关闭模态框。
// @src/components/Modal.jsx
import React from "react";
import styles from "./Modal.module.css";
import { RiCloseLine } from "react-icons/ri";
const Modal = ({ setIsOpen }) => {
return (
<>
<div className={styles.darkBG} onClick={() => setIsOpen(false)} />
<div className={styles.centered}>
<div className={styles.modal}>
<div className={styles.modalHeader}>
<h5 className={styles.heading}>Dialog</h5>
</div>
<button className={styles.closeBtn} onClick={() => setIsOpen(false)}>
<RiCloseLine style={{ marginBottom: "-3px" }} />
</button>
// ...
</div>
</div>
</>
);
};
export default Modal;
现在我们可以添加模态框的内容(.modalContent)并添加一条消息。
// @src/components/Modal.jsx
import React from "react";
import styles from "./Modal.module.css";
import { RiCloseLine } from "react-icons/ri";
const Modal = ({ setIsOpen }) => {
return (
<>
<div className={styles.darkBG} onClick={() => setIsOpen(false)} />
<div className={styles.centered}>
<div className={styles.modal}>
<div className={styles.modalHeader}>
<h5 className={styles.heading}>Dialog</h5>
</div>
<button className={styles.closeBtn} onClick={() => setIsOpen(false)}>
<RiCloseLine style={{ marginBottom: "-3px" }} />
</button>
<div className={styles.modalContent}>
Are you sure you want to delete the item?
</div>
// ...
</div>
</div>
</>
);
};
export default Modal;
我们现在就可以开始编写操作步骤了。这样,我们就可以添加包装样式及其按钮。
// @src/components/Modal.jsx
import React from "react";
import styles from "./Modal.module.css";
import { RiCloseLine } from "react-icons/ri";
const Modal = ({ setIsOpen }) => {
return (
<>
<div className={styles.darkBG} onClick={() => setIsOpen(false)} />
<div className={styles.centered}>
<div className={styles.modal}>
<div className={styles.modalHeader}>
<h5 className={styles.heading}>Dialog</h5>
</div>
<button className={styles.closeBtn} onClick={() => setIsOpen(false)}>
<RiCloseLine style={{ marginBottom: "-3px" }} />
</button>
<div className={styles.modalContent}>
Are you sure you want to delete the item?
</div>
<div className={styles.modalActions}>
<div className={styles.actionsContainer}>
<button className={styles.deleteBtn} onClick={() => setIsOpen(false)}>
Delete
</button>
<button
className={styles.cancelBtn}
onClick={() => setIsOpen(false)}
>
Cancel
</button>
</div>
</div>
</div>
</div>
</>
);
};
export default Modal;
现在模态框组件已经完成,只需将其添加到我们的页面即可。App.jsx但首先,让我们创建以下样式,以便在页面上添加一个更方便的按钮:
/* @src/App.module.css */
.primaryBtn {
margin: 20px 10px;
cursor: pointer;
font-weight: 500;
padding: 13px 25px;
border-radius: 15px;
font-size: 0.8rem;
border: none;
color: white;
background: #185adb;
transition: all 0.25s ease;
}
.primaryBtn:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px -10px rgba(24, 90, 219, 0.6);
}
现在我们可以开始着手开发了App.jsx。首先,我们将导入相关库useState(),并创建一个名为 isOpen 的状态和 setIsOpen 函数。
// @src/App.jsx
import React, { useState } from "react";
import styles from "./App.module.css";
const App = () => {
const [isOpen, setIsOpen] = useState(false);
return (
<main>
<button className={styles.primaryBtn} onClick={() => setIsOpen(true)}>
Open Modal
</button>
// ...
</main>
);
};
export default App;
然后我们进行条件渲染,仅当 isOpen 状态为 true 时才显示模态框。同样,我们会将该setIsOpen()函数作为 prop 传递。
// @src/App.jsx
import React, { useState } from "react";
import styles from "./App.module.css";
import Modal from "./components/Modal";
const App = () => {
const [isOpen, setIsOpen] = useState(false);
return (
<main>
<button className={styles.primaryBtn} onClick={() => setIsOpen(true)}>
Open Modal
</button>
{isOpen && <Modal setIsOpen={setIsOpen} />}
</main>
);
};
export default App;
你应该会得到类似这样的结果:
结论
和往常一样,希望您觉得这篇文章有趣。如果您发现文章中有任何错误,请在评论区指出。🤩
祝你今天过得愉快!🪗 🙌
文章来源:https://dev.to/franciscomendes10866/how-to-create-a-modal-in-react-3coc