我正在此question
上使用代码共享该代码仅适用于一个模态,我试图添加多个,但是当我第一次单击它时,所有模态都被触发,然后它正常工作,这是我面临的唯一问题
Modal.js
import React, { useRef, useEffect } from "react";
import { createPortal } from "react-dom";
const Modal = ({ isOpen, type, onClose, children }) => {
const modalEl = useRef(null);
const handleCoverClick = e => {
if (e.target.hasAttribute("modal")) {
onClose();
}
};
useEffect(() => {
const handleAnimationEnd = event => {
if (isOpen.type === type && isOpen.modal) {
if (!isOpen.modal) {
event.target.classList.remove("show");
event.target.classList.add("hide");
} else {
event.target.classList.remove("hide");
event.target.classList.add("show");
}
}
};
modalEl.current.addEventListener("animationend", handleAnimationEnd);
return () =>
modalEl.current.removeEventListener("animationend", handleAnimationEnd);
}, [isOpen]);
return createPortal(
<>
<div
className={`ModalCover ${isOpen ? "show" : "hide"}`}
onClick={handleCoverClick}
modal="true"
/>
<div
className={`
ModalContainer
${isOpen.type === type && isOpen.modal ? "slide-up" : "slide-down"}
${!modalEl.current && "hide"}
`}
ref={modalEl}
>
{children}
</div>
</>,
document.body
);
};
export default Modal;
Style.css
.App {
font-family: sans-serif;
text-align: center;
}
.show {
display: block;
}
.hide {
display: none;
}
.slide-up {
transform: translateY(0%);
animation: slide-up 0.5s forwards;
}
.slide-down {
transform: translateY(100%);
animation: slide-down 0.5s forwards;
}
@keyframes slide-up {
0% {
transform: translateY(100%);
}
100% {
transform: translateY(0%);
}
}
@keyframes slide-down {
0% {
transform: translateY(0%);
}
100% {
transform: translateY(100%);
}
}
.ModalCover {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 10;
background-color: rgba(0, 0, 0, 0.15);
}
.ModalContainer {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 400px;
margin-top: calc(100vh - 400px);
z-index: 20;
}
Index.js
import React, { useState } from "react";
import ReactDOM from "react-dom";
import Modal from "./Modal";
import "./styles.css";
function App() {
const [isOpen, setIsOpen] = useState(false);
return (
<div className="App">
<Modal isOpen={isOpen} onClose={() => setIsOpen(false)}>
<div>
<h3>Coockie</h3>
<p>content about coockies</p>
<button
aria-label="Close this popup"
onClick={() => setIsOpen({ type: "coockie", modal: false })}
className="closeBtn"
>
x
</button>
</div>
</Modal>
<Modal isOpen={isOpen} onClose={() => setIsOpen(false)}>
<div>
<h3>About us</h3>
<p>content about us</p>
<button
aria-label="Close this popup"
onClick={() => setIsOpen({ type: "about-us", modal: false })}
className="closeBtn"
>
x
</button>
</div>
</Modal>
<button onClick={() => setIsOpen({ content: "coockie", modal: true })}>
coockie modal
</button>
<button onClick={() => setIsOpen({ content: "about-us", modal: true })}>
about us modal
</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
答案 0 :(得分:0)
更正:-
1)我们不希望在isOpen
为真之前渲染模式
2)根据ModalContainer
的标志更正显示和隐藏,而不是在参考值modalEl.current
中填充当前值。
3)您对两个模态使用相同的状态和更新方法。创建单独的状态,您应该一切顺利。目前,我有isOpen1
和isOpen2
这两个名字,但是您可以给出更有意义的名字。
// index.js
import React, { useState } from "react";
import ReactDOM from "react-dom";
import Modal from "./Modal";
import "./styles.css";
function App() {
const [isOpen1, setIsOpen1] = useState(false);
const [isOpen2, setIsOpen2] = useState(false);
return (
<div className="App">
<>
{isOpen1 && (
<Modal isOpen={isOpen1} onClose={() => setIsOpen1(false)}>
<div>
<h3>Coockie</h3>
<p>content about coockies</p>
<button
aria-label="Close this popup"
onClick={() => setIsOpen1(false)}
className="closeBtn"
>
x
</button>
</div>
</Modal>
)}
</>
<>
{isOpen2 && (
<Modal isOpen={isOpen2} onClose={() => setIsOpen2(false)}>
<div>
<h3>About us</h3>
<p>content about us</p>
<button
aria-label="Close this popup"
onClick={() => setIsOpen2(false)}
className="closeBtn"
>
x
</button>
</div>
</Modal>
)}
</>
<button onClick={() => setIsOpen1(true)}>coockie modal</button>
<button onClick={() => setIsOpen2(true)}>about us modal</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
// Modal.js
import React, { useRef, useEffect } from "react";
import { createPortal } from "react-dom";
const Modal = ({ isOpen, onClose, children }) => {
const modalEl = useRef(null);
const handleCoverClick = e => {
if (e.target.hasAttribute("modal")) {
onClose();
}
};
useEffect(() => {
const handleAnimationEnd = event => {
if (!isOpen) {
event.target.classList.remove("show");
event.target.classList.add("hide");
} else {
event.target.classList.remove("hide");
event.target.classList.add("show");
}
};
const modalRef = modalEl.current;
modalEl.current.addEventListener("animationend", handleAnimationEnd);
return () =>
modalRef.removeEventListener("animationend", handleAnimationEnd);
}, [isOpen]);
return createPortal(
<>
<div
className={`ModalCover ${isOpen ? "show" : "hide"}`}
onClick={handleCoverClick}
modal="true"
/>
<div
className={`
ModalContainer
${isOpen ? "slide-up show" : "slide-down hide"}
`}
ref={modalEl}
>
{children}
</div>
</>,
document.body
);
};
export default Modal;