本文譯自:30-seconds-of-react 。 React 30 秒速學: 精選有用的 React 片斷,30-seconds-of-react 的中文版本,已所有完成翻譯、上線,地址:30-seconds-of-react-zh_CN-umi 。css
系列文章:react
可經過事件控制的模態組件。git
要使用該組件,只導入一次Modal
,而後經過將一個布爾值傳遞給isVisible
屬性來顯示它。github
keydownHandler
方法,用於處理全部鍵盤事件,能夠根據你的須要使用它來調度動做(例如,當按下Esc時關閉模態)。 *使用React.useEffect()
hook來添加或刪除keydown
事件監聽器,它調用keydownHandler
。 *使用isVisible
道具來肯定是否應該顯示模態。 *使用CSS來設置和定位模態組件。樣式:web
.modal {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right:0;
width: 100%;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.25);
animation-name: appear;
animation-duration: 300ms;
}
.modal-dialog{
width: 100%;
max-width: 550px;
background: white;
position: relative;
margin: 0 20px;
max-height: calc(100vh - 40px);
text-align: left;
display: flex;
flex-direction: column;
overflow:hidden;
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
-webkit-animation-name: animatetop;
-webkit-animation-duration: 0.4s;
animation-name: slide-in;
animation-duration: 0.5s;
}
.modal-header,.modal-footer{
display: flex;
align-items: center;
padding: 1rem;
}
.modal-header{
border-bottom: 1px solid #dbdbdb;
justify-content: space-between;
}
.modal-footer{
border-top: 1px solid #dbdbdb;
justify-content: flex-end;
}
.modal-close{
cursor: pointer;
padding: 1rem;
margin: -1rem -1rem -1rem auto;
}
.modal-body{
overflow: auto;
}
.modal-content{
padding: 1rem;
}
@keyframes appear {
from {opacity: 0;}
to {opacity: 1;}
}
@keyframes slide-in {
from {transform: translateY(-150px);}
to { transform: translateY(0);}
}
複製代碼
組件:數組
import React from "react";
import styles from "./Modal.css";
function Modal({ isVisible = false, title, content, footer, onClose }) {
React.useEffect(() => {
// 監聽事件
document.addEventListener("keydown", keydownHandler);
// 取消監聽
return () => document.removeEventListener("keydown", keydownHandler);
});
function keydownHandler({ key }) {
// esc 鍵,關閉模態框
switch (key) {
case "Escape":
onClose();
break;
default:
}
}
// 控制模態框顯示
return !isVisible ? null : (
<div className={styles["modal"]} onClick={onClose}> <div className={styles["modal-dialog"]} onClick={e => e.stopPropagation()} > <div className={styles["modal-header"]}> <h3 className={styles["modal-title"]}>{title}</h3> <span className={styles["modal-close"]} onClick={onClose}> × </span> </div> <div className={styles["modal-body"]}> <div className={styles["modal-content"]}>{content}</div> </div> {footer && <div className={styles["modal-footer"]}>{footer}</div>} </div> </div>
);
}
複製代碼
例子app
// 將組件添加到 render 函數
function App() {
const [isModal, setModal] = React.useState(false);
return (
<React.Fragment>
{/* 按鈕顯示模態框 */}
<button onClick={() => setModal(true)}>顯示模態框</button>
<Modal
isVisible={isModal}
title="標題"
content={<p>正文</p>}
footer={<button onClick={() => setModal(false)}>關閉模態框</button>}
onClose={() => setModal(false)}
/>
</React.Fragment>
);
}
export default function() {
return <App />;
}
複製代碼