React createPortal 调用失败,因为 document.body 不存在?

React createPortal call fails because document.body doesn't exist?

我有一个模态对话框的 React 组件。当我不对它做任何特别的事情时它工作得很好:

return (
    <Modal className={isShowing ? "modal is-active" : "modal"}>
        <ModalBackground></ModalBackground>
        <ModalCard>
            <ModalHeader>
                <ModalTitle>
                    <NoticeIcon type={noticeType}/>
                    {title}
                </ModalTitle>
                <ModalClose onClick={handleHideModal}></ModalClose>
            </ModalHeader>
            <ModalContent>
                {content}
            </ModalContent>
            <ModalFoot>
                { buttonSpecs.map((spec) => 
                    <BottomButton key={spec.label} label={spec.label} handleClick={spec.handleClick} isPrimary={spec.isPrimary} />
                )}
            </ModalFoot>
        </ModalCard>
    </Modal>
);

但是,显示对话框的规定方法是将其显示在 DOM 文档的底部,而不是嵌入恰好调用它的任何组件中,包括组件的外部 DOM 元素甚至可能不允许。 (事实上​​ ,在一种情况下,我从呈现 table 行的组件内部调用模态对话框,在 TR 处。它 "works" 但它会触发 Chrome 的错误消息控制台,因为在 TR 中只允许 TH 和 TD)。这样做的方法是 ReactDOM.createPortal:

import ReactDOM from 'react-dom';
...
return (ReactDOM.createPortal(
    <Modal className={isShowing ? "modal is-active" : "modal"}>
        <ModalBackground></ModalBackground>
        <ModalCard>
            <ModalHeader>
                <ModalTitle>
                    <NoticeIcon type={noticeType}/>
                    {title}
                </ModalTitle>
                <ModalClose onClick={handleHideModal}></ModalClose>
            </ModalHeader>
            <ModalContent>
                {content}
            </ModalContent>
            <ModalFoot>
                { buttonSpecs.map((spec) => 
                    <BottomButton key={spec.label} label={spec.label} handleClick={spec.handleClick} isPrimary={spec.isPrimary} />
                )}
            </ModalFoot>
        </ModalCard>
    </Modal>
), document.body);

调用 ReactDOM.createPortal,将 document.body 作为其第二个参数,应该在主体的末尾呈现组件。但它给了我一个错误:"Target container is not a DOM element".

在我显示对话框时,页面和其中的所有其他内容都已经存在,因此正文存在。

我已经尝试了另一种我已经解释过的方法,即在文档的外部 HTML 结构的末尾创建一个显式的 div 作为模态的容器:

<div id="root"></div>
<div id="modalRoot"></div>

然后用 document.getElementById('modalRoot') 代替 document.body。但这给了我同样的错误。

我为此找到的唯一答案涉及在第一次呈现时通过文档的 HEAD 部分中的脚本调用模态的情况,因此主体尚不存在。在这些情况下,建议将脚本移至文档末尾。在我的例子中,显示对话框是为了响应我在已经呈现的文档中的某些操作。

有什么想法吗?

import ReactDOM from 'react-dom';
...
return ReactDOM.createPortal(
    <Modal className={isShowing ? "modal is-active" : "modal"}>
        <ModalBackground></ModalBackground>
        <ModalCard>
            <ModalHeader>
                <ModalTitle>
                    <NoticeIcon type={noticeType}/>
                    {title}
                </ModalTitle>
                <ModalClose onClick={handleHideModal}></ModalClose>
            </ModalHeader>
            <ModalContent>
                {content}
            </ModalContent>
            <ModalFoot>
                { buttonSpecs.map((spec) => 
                    <BottomButton key={spec.label} label={spec.label} handleClick={spec.handleClick} isPrimary={spec.isPrimary} />
                )}
            </ModalFoot>
        </ModalCard>
    </Modal>
), document.body);

您的函数应该 return 对象 return 由 ReactDOM.createPortal 函数编辑。您在 return 函数的开头添加了额外的 (。参考:https://reactjs.org/docs/portals.html#usage