【发布时间】:2021-10-26 23:33:31
【问题描述】:
我正在尝试使用自定义关闭回调实现模式。我使用一个 useState 挂钩来完成此操作,该挂钩存储此方法并在已定义的 closeModal() 中执行它。 我的问题是,当我尝试从上下文中使用 closeModal 时,回调会保留初始值,而不是更新后的值。
function ModalProvider({ children }) {
const [component, setComponent] = useState<React.ReactNode>(null);
const [styles, setStyles] = useState<React.CSSProperties>(null);
const [onClose, setOnClose] = useState<() => void>(null);
const openModal = ({
component,
containerStyles,
onClose,
}: OpenModalProps) => {
setComponent(component);
setStyles(containerStyles);
setOnClose(() => onClose);
};
const closeModal = () => {
onClose?.();
setComponent(null);
setStyles(null);
setOnClose(null);
};
return (
<ModalContext.Provider value={{ component, styles, openModal, closeModal }}>
{children}
</ModalContext.Provider>
);
}
所以这里我分两点使用,按钮和自定义钩子useClickOutside。当我单击按钮时,它可以正常工作,但是当从钩子中捕获事件时,会发生模式关闭但 onClose 未执行,因为它为空。
function Modal() {
const { component, styles, closeModal } = useContext(ModalContext);
const contentRef = useRef<HTMLDivElement>(null);
const [stopScrolling, continueScrolling] = useStopScrolling();
useClickOutside(contentRef, closeModal);
useEffect(() => {
if (!component) continueScrolling();
if (component) stopScrolling();
}, [component]);
if (!component) return <></>;
return (
<>
<S.ModalWrapper>
<section style={styles} ref={contentRef}>
<button onClick={closeModal}>x</button>
{component}
</section>
</S.ModalWrapper>
</>
);
}
function useClickOutside(ref, onClickOutside: () => void) {
const handleClickOutside = (event) => {
if (ref.current && !ref.current.contains(event.target)) {
onClickOutside();
}
};
useEffect(() => {
document.addEventListener("mousedown", handleClickOutside);
return () => {
window.removeEventListener("mousedown", handleClickOutside);
};
}, [ref]);
}
我在其他应用点上使用此方法也失败了,但我认为这足以发现问题。谢谢。
编辑
这就是我调用模态的方式
openModal({
component: <QuickView product={product} close={closeModal} />,
containerStyles: {
width: "80%",
maxWidth: "1000px",
height: "auto",
backgroundColor: "transparent",
},
onClose: () => {
const as = router.asPath;
router.push(as, as, { shallow: true });
},
});
【问题讨论】:
-
请注意,您传递给
openModal的component也将包含陈旧的closeModal。
标签: reactjs typescript next.js use-context