如果在内容之外单击,则 React Modal 关闭
React Modal close if is clicked outside of content
我已经创建了一个自定义 React 模态组件,我希望重构能够跟踪模态内容的外部点击并能够关闭模态我的代码如下所示。如果点击在 popup
容器之外,我会寻找一种解决方法来删除创建门户,
import React from "react";
import ReactDOM from "react-dom";
const Hint = (props) => {
const ToggleContent = ({ toggle, content }) => {
const [isShown, setIsShown] = React.useState(false);
const hide = () => setIsShown(false);
const show = () => setIsShown(true);
return (
<React.Fragment>
{toggle(show)}
{isShown && content(hide)}
</React.Fragment>
);
};
const Modal = ({ children }) => {
return ReactDOM.createPortal(
<div className="modal">{children}</div>,
document.body
);
};
return (
<div className={"hint"}>
<ToggleContent
toggle={(show) => (
<div className={"hint__icon"} onClick={show}>
{props.hintLabel ? (
<div className={"hint__label-text"}>{props.hintLabel}</div>
) : null}
</div>
)}
content={(hide) => (
<div className={"modal__body"}>
<Modal>
<div className={"popup"}>
<div className={"popup__wrapper"}>
<div
className={"popup__content"}
dangerouslySetInnerHTML={{ __html: props.content }}
></div>
</div>
<button onClick={hide} type="button" className="close">
X
</button>
</div>
</Modal>
</div>
)}
/>
</div>
);
};
ReactDOM.render(
<Hint hintLabel="test" content="teasasd ajsdghajsdg" />,
document.getElementById("app")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
我想,这个钩子可以帮到你。
export const useClickOutside = (
insideRefs,
isVisible,
onClose,
) => {
useEffect(() => {
const handleWindowClick = (event) => {
const someRefContainTarget = insideRefs
.filter((ref) => ref.current)
.some((ref) => ref.current.contains(event.target));
if (someRefContainTarget) {
return;
}
if (!isVisible) {
return;
}
if (onClose) {
onClose();
}
};
if (isVisible) {
window.addEventListener('click', handleWindowClick);
}
return () => {
if (isVisible) {
window.removeEventListener('click', handleWindowClick);
}
};
}, [isVisible, onClose]);
};
只需传递 onClose
-处理程序、可见性状态(在您的情况下为 isShown
)和所有 inside 元素的引用。
使用 react-native-modal 包,其中有一个道具调用 onBackDrop press 可以完成你的工作
或者,如果您不想添加 react-native-modal 包,则有解决方法
<Modal visible={showModal} transparent>
<TouchableOpacity
onPress={() => setShowModal(false)}
style={{
position: 'absolute',
width: wp(100),
height: hp(100),
backgroundColor: allColor.darkGreyOpacity,
}}></TouchableOpacity>
<View>
//you code goes herere
</View>
</Modal>
``
我已经创建了一个自定义 React 模态组件,我希望重构能够跟踪模态内容的外部点击并能够关闭模态我的代码如下所示。如果点击在 popup
容器之外,我会寻找一种解决方法来删除创建门户,
import React from "react";
import ReactDOM from "react-dom";
const Hint = (props) => {
const ToggleContent = ({ toggle, content }) => {
const [isShown, setIsShown] = React.useState(false);
const hide = () => setIsShown(false);
const show = () => setIsShown(true);
return (
<React.Fragment>
{toggle(show)}
{isShown && content(hide)}
</React.Fragment>
);
};
const Modal = ({ children }) => {
return ReactDOM.createPortal(
<div className="modal">{children}</div>,
document.body
);
};
return (
<div className={"hint"}>
<ToggleContent
toggle={(show) => (
<div className={"hint__icon"} onClick={show}>
{props.hintLabel ? (
<div className={"hint__label-text"}>{props.hintLabel}</div>
) : null}
</div>
)}
content={(hide) => (
<div className={"modal__body"}>
<Modal>
<div className={"popup"}>
<div className={"popup__wrapper"}>
<div
className={"popup__content"}
dangerouslySetInnerHTML={{ __html: props.content }}
></div>
</div>
<button onClick={hide} type="button" className="close">
X
</button>
</div>
</Modal>
</div>
)}
/>
</div>
);
};
ReactDOM.render(
<Hint hintLabel="test" content="teasasd ajsdghajsdg" />,
document.getElementById("app")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
我想,这个钩子可以帮到你。
export const useClickOutside = (
insideRefs,
isVisible,
onClose,
) => {
useEffect(() => {
const handleWindowClick = (event) => {
const someRefContainTarget = insideRefs
.filter((ref) => ref.current)
.some((ref) => ref.current.contains(event.target));
if (someRefContainTarget) {
return;
}
if (!isVisible) {
return;
}
if (onClose) {
onClose();
}
};
if (isVisible) {
window.addEventListener('click', handleWindowClick);
}
return () => {
if (isVisible) {
window.removeEventListener('click', handleWindowClick);
}
};
}, [isVisible, onClose]);
};
只需传递 onClose
-处理程序、可见性状态(在您的情况下为 isShown
)和所有 inside 元素的引用。
使用 react-native-modal 包,其中有一个道具调用 onBackDrop press 可以完成你的工作
或者,如果您不想添加 react-native-modal 包,则有解决方法
<Modal visible={showModal} transparent>
<TouchableOpacity
onPress={() => setShowModal(false)}
style={{
position: 'absolute',
width: wp(100),
height: hp(100),
backgroundColor: allColor.darkGreyOpacity,
}}></TouchableOpacity>
<View>
//you code goes herere
</View>
</Modal>
``