如何在 React 中延迟加载无头 ui 对话框?

问题描述 投票:0回答:2

我正在尝试延迟加载无头 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
是假的然后它会立即被卸载。但是,如果我删除它,那么当我打开它时,组件不会延迟加载,而是在页面加载时加载。

有没有办法在保持过渡的同时延迟加载它?

javascript reactjs next.js lazy-loading headless-ui
2个回答
0
投票

一个选项是有2个标志,一个用于模态

open
状态,第二个用于模态
visible
状态

然后我们可以添加一个效果,“监听”

open
状态的变化,当
transitionend
状态变为
open
时,在模态元素上添加
false
事件监听器, 我们将设置事件回调以将模态的
visible
状态更改为
false
并且一旦转换结束它就会被触发

你可以在这里看到一个例子: Edit gifted-rain-zpz2p7


0
投票

另一种选择是通过渲染道具将模式拆分为容器和实际内容。这样只有模态的必要部分才会在页面的初始加载时呈现。在用户决定打开模式之前,内容逻辑不会被渲染。

Edit nervous-sun-vgsmmc

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>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.