使用Portal而不是将组件作为prop传递有什么弊端?

时间:2019-01-19 11:23:35

标签: reactjs

假设我们有一个SidebarLayout组件,可呈现以下HTML:

<div id="sidebar-layout">
    <div id="sidebar"></div>
    <div id="content"></div>
</div>

要添加侧边栏内容,我可以轻松地传递另一个组件作为道具,例如:

<SidebarLayout sidebarContent={() => (<SomeOtherComponent />)}>
    ...
</SidebarLayout>

,然后为render提供SidebarLayout函数,如下所示:

class SidebarLayout extends React.Component {
    ...

    render() {
        const { sidebarContent: SidebarContent } = this.props;

        return (
            <div id="sidebar-layout">
                <div id="sidebar">
                    {SidebarContent &&
                        <SidebarContent />
                    }
                </div>
                <div id="content" />
            </div>
        )
   }
}

到目前为止,这就是我们的工作方式。但是,React 16引入了Portal,使我们可以在其原始React树之外渲染组件,典型示例通常以模式,弹出窗口等形式给出。

门户还使它们也可以用于将元素放置在自己的父对象中。这意味着使用以下代码可以实现与上述完全相同的结果(省略了不太重要的代码):

class SidebarLayout extends React.Component {
    ...

    render() {
        return (
            <div id="sidebar-layout">
                <div id="sidebar" />
                <div id="content" />
            </div>
        )
   }
}
class SidebarContentPortal extends React.Component {
    portalId = "sidebar";

    constructor(props) {
        super(props);

        this.el = document.createElement("div");
    }

    componentDidMount() {
        const contentBar = document.getElementById(this.portalId);

        contentBar.appendChild(this.el);
    }

    componentWillUnmount() {
        const contentBar = document.getElementById(this.portalId);

        contentBar.removeChild(this.el);
    }

    render() {
        return ReactDOM.createPortal(
            this.props.children,
            this.el
        );
    }
}

现在我们将SidebarContentPortal用作:

<SidebarLayout>
    ...
    <SidebarContentPortal>
        ...
    </SidebarContentPortal>
</SidebarLayout>

我想知道以这种确切的方式使用门户网站是否有缺点或弊端,而不是在引入门户网站之前将组件作为道具来传递?

0 个答案:

没有答案