我在我的React应用程序中使用了Next JS,但在门户网站中创建模式时遇到了麻烦,它引发了错误“目标容器不是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);
答案 0 :(得分:9)
接受的答案不是最佳选择。当服务器呈现的内容与客户端的不同时,您可能会遇到很多呈现问题。主要思想是在SSR和水化过程中具有相同的内容。在您的情况下,使用 { ssr: false }
选项加载模态 dynamically 会更准确。
作为第二个选项,请注意 next's example。在服务器和客户端的初始渲染期间,它们总是返回 null
,这是正确的方法。
答案 1 :(得分:0)
由于未初始化container
,因此在ssr期间它将中断。您可以尝试在没有门户时跳过渲染:
return container ? ReactDOM.createPortal(element, container) : null;
答案 2 :(得分:0)
如果您想拥有一个可以与服务器端渲染一起使用的“门户”(即,客户端会收到一个与搜索引擎一起使用的非空门户),则不能使用ReactDOM。
要具有完全SSR的“门户”,请在以下位置查看next.js对元素的作用(扰流器:门户):https://github.com/vercel/next.js/blob/canary/packages/next/next-server/lib/head.tsx