我正在尝试延迟加载无头 ui 对话框组件,但我无法在保持转换的同时做到这一点。
这里离我最近的地方:
// Modal.js
const Modal = ({
isOpen
}) => {
return (
<Transition show={isOpen}>
<Dialog>
...
</Dialog>
</Transition>
);
};
export default Modal;
const Modal = lazy(() => import("~/components/Modal"));
<Suspense>
{isOpen ? <Modal isOpen={isOpen} ... />
</Suspense>
这在大多数情况下都有效,但是当组件被卸载时我失去了过渡,因为
isOpen
是假的然后它会立即被卸载。但是,如果我删除它,那么当我打开它时,组件不会延迟加载,而是在页面加载时加载。
有没有办法在保持过渡的同时延迟加载它?
另一种选择是通过渲染道具将模式拆分为容器和实际内容。这样只有模态的必要部分才会在页面的初始加载时呈现。在用户决定打开模式之前,内容逻辑不会被渲染。
Modal.tsx
type ModalProps = {
isOpen: boolean;
onClose: VoidFunction;
renderTitle?: () => ReactNode;
renderContent: (config: { onClose: VoidFunction }) => ReactNode;
};
export function Modal({
isOpen,
onClose,
renderContent,
renderTitle
}: ModalProps) {
return (
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" onClose={onClose}>
<Dialog.Panel>
<Dialog.Title>{renderTitle?.()}</Dialog.Title>
{renderContent({ onClose })}
</Dialog.Panel>
</Dialog>
</Transition>
);
}
const ModalContent = lazy(() => import("./modal-content"));
<Modal
isOpen={isOpen}
onClose={closeModal}
renderTitle={() => <span>Title</span>}
renderContent={(props) => (
<Suspense>
<ModalContent {...props} />
</Suspense>
)}
/>
function ModalContent({ onClose }: { onClose: VoidFunction }) {
console.log(`Render ${ModalContent.name}`);
return (
<div>
<p>Hi, Text!</p>
<button type="button" onClick={onClose}>
Got it, thanks!
</button>
</div>
);
}