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

时间:2018-03-27 04:47:36

标签: javascript html reactjs

我理解it's probably a bad ideaReactDOM.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
        );
    }
}

没有遇到这种模式的任何问题,但我想知道在我开始添加更多库时是否会产生后果。

2 个答案:

答案 0 :(得分:4)

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

如果此类上下文的父级是body元素,那么会产生相同数量的意外惊喜,就像通过第三方工具插入其中的元素一样,如{{{ 3}}。简单地说:由于来自第三方的那些DOM突变发生在React的控制范围之外,但是修改了在React控制下的DOM部分,它可能导致冲突和不一致。

另一点@RIYAJ KHAN在他的评论中已经上升如果突然门户网站成为应用程序的父级会发生什么,特别是如果React看到它们的另一种方式?我能想到的最少的是 native 合成 DOM事件传播之间的不一致,其中这两者会在app和portal容器之间以相反的方向传播事件,这会令人难以置信如果您经常使用两种类型的事件处理(例如,React组件的事件处理程序中的合成和RxJS运算符中的 native )。

最后但并非最不重要的是,如果您有更多此类门户哪些应该位于最高DOM级别,那么您是否要重用所有这些门户网站的body?这与上面的2点一起会造成混乱。

最安全的方法是在门户网站的div下创建专用的body,这样他们就可以保持干净,没有多余的魔法。

答案 1 :(得分:1)

到目前为止,我们在Material-UI上的经验是,它很安全:https://github.com/mui-org/material-ui/issues/21626。我们尚未见过使用该库的100万+开发人员之一报告的任何限制。