reactjs 我们能否在Next.js中创建门户

sqyvllje  于 2022-12-26  发布在  React
关注(0)|答案(3)|浏览(125)

我正在使用Next.js和我的React应用程序,我在门户中创建模态时遇到了一个问题,它抛出了一个错误 “目标容器不是DOM元素。”,这是我的代码。

import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import classes from './listModal.scss';

const EditorListModal = (props) => {
  let container;
  if (typeof window !== 'undefined') {
    const rootContainer = document.createElement('div');
    const parentElem = document.querySelector('#__next');
    parentElem.appendChild(rootContainer);
    container = rootContainer;
  }
  const isShown = props.show ? classes['editor-listModal--open'] : '';
  const element = (
    <div className={`${classes['editor-listModal']} ${isShown}`}>
      // Modal Content
    </div>
  );

  return ReactDOM.createPortal(element, container);
};

EditorListModal.propTypes = {
  show: PropTypes.bool
};

export default React.memo(EditorListModal);
ubbxdtey

ubbxdtey1#

可接受的答案不是最佳选项。当服务器呈现的内容与客户端呈现的内容不同时,您可能会遇到很多呈现问题。主要思想是在SSR和水合过程中保持相同的内容。在您的情况下,使用{ ssr: false }选项动态加载模态会更准确。
作为第二个选项,在next's example处做一个记录。在服务器和客户端上初始渲染时,它们总是返回null,这是一个正确的方法。

2w2cym1i

2w2cym1i2#

由于container未初始化,它将在ssr期间中断。您可以尝试在没有门户时跳过渲染:

return container ? ReactDOM.createPortal(element, container) : null;
iugsix8n

iugsix8n3#

// dpeending on your component needs
interface ModalProps {
  onCancelModal: () => void;
  onAcceptModal?: () => void;
  acceptEnabled?: boolean;
  isLoading?: boolean;
  title: string;
}
const Modal: React.FC<ModalProps> = (props) => {
  // let container: HTMLDivElement | null = null;
  let containerRef = useRef<HTMLDivElement | null>(null);
  useEffect(() => {
    const rootContainer = document.createElement("div");
    rootContainer.className = "modall";
    const parentElem = document.querySelector("#__next");
    
    parentElem?.insertAdjacentElement("afterend", rootContainer);
    if (!containerRef.current) {
      containerRef.current = rootContainer;
    }

    // clean it from dom
    return () => rootContainer.remove();
  }, [containerRef]);
  
  return containerRef.current
    ? ReactDOM.createPortal(
        <>
         {/* place modal jsx here */}
        </>,
        containerRef.current
      )
    : null;
  // return null;
};

export default Modal;

相关问题