将ReactDOM.createPortal()与document.body一起使用是否安全?

Dan*_*iel 9 html javascript reactjs

据我所知,它可能是一个坏主意来ReactDOM.render()成document.body.但是,有没有使用任何的问题ReactDOM.createPortal()用document.body?

当你渲染成身体时,试图寻找React去疯狂的例子,所以我可以用createPortal测试它,但我找不到任何东西.

把事情放到上下文中,这是我正在谈论的示例用法:

import React from 'react';
import ReactDOM from 'react-dom';

export default class Modal extends React.Component {
    render() {
        return ReactDOM.createPortal(
            <div className='modalContainer'>
                <div className='modalBox'>
                    {this.props.children}
                </div>
            </div>,
            document.body
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

没有遇到这种模式的任何问题,但我想知道是否有后果,因为我开始添加更多的库.

Dan*_*cák 5

我非常确定,与的用法相同的规则也适用于门户网站ReactDOM.render。根据您提供的门户网站文档,从React的角度来看,门户确实是React应用程序的子级(考虑例如合成DOM事件传播的方向),但是门户在物理上位于单独的上下文中,其中React仍然需要跟踪状态变化并与DOM同步。

如果这样的上下文的父body元素是元素,那么像Dan Abramov的文章中所述的通过第三方工具将元素插入到元素中一样,同样数量的不必要的惊喜也将受到威胁。简而言之:由于来自第三方的那些DOM突变发生在React的控制之外,因此BUT修改了在React控制下的DOM部分,这可能导致冲突和不一致。

@RIYAJ KHAN在评论中提到的另一点是,如果门户突然成为应用程序的父级,特别是在React看到它们相反的情况下,会发生什么?我能想到的至少有不一致天然和合成的 DOM事件传播,其中两个人会传播中的应用程序和门户容器之间相反的方向,由此可得让人难以置信,如果你经常使用这两种类型的事件处理(例如事件合成的React组件的事件处理程序以及RxJS运算符中的本机事件处理程序。

最后但并非最不重要的一点是,如果您有更多这样的门户网站应该在顶级DOM级别上,您将对body所有这些门户网站重新使用吗?再加上以上两点,将会造成动荡。

最安全的方法是在Portal 专用的divs下创建专用的body,这样它们可以保持干净并且没有有害的魔法。