【问题标题】:How can I render a component in DOM body even if some other component renders it in react?即使其他一些组件在反应中呈现它,我如何在 DOM 主体中呈现组件?
【发布时间】:2016-12-31 14:29:03
【问题描述】:

我有一个组件,比如X,它由我的app 渲染并在DOM-body 中。我有另一个组件Y 由组件X 呈现,但组件Y 应该全屏打开。所以,我需要在 document.body 而不是在组件 X 中渲染它,即使 X 渲染它。

React 组件的结构是:

app
    -X
         -Y (in Full Screen)

现在的结构应该是这样的:

<body>
    <div class="X">
         <div class="Y">
         </div>
    </div>
</body>

渲染的流程应该是:

app.body
    -X
-Y

并且DOM结构应该是:

<body>
    <div class="X">
    </div>
    <div class="Y">
    </div>
</body>

我该怎么做。另外,我正在使用 ES6 类来制作 react-components。

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    只需在自己的&lt;div&gt; 中渲染每个组件:

    <body>
        <div id="app"></div>
        <div id="Y"></div>
    </body>
    

    并分别渲染每个组件:

    React.render(ComponentApp, document.getElementById("app"));
    React.render(ComponentX, document.getElementById("X"));
    

    【讨论】:

    • X 是由Y 渲染的。我知道 DOM 的结构应该是这样的,但我该怎么做呢?
    • 将 ES6 类用于 React 组件,那么我该怎么写呢?你能告诉我吗
    • 根据您描述情况的方式,您不应该在Y 中呈现X,因为它们在逻辑上不适合层次结构。 Y 是否有来自 X 的任何数据?如果是这样,你能通过其他方式获得它吗(例如,像 redux 这样的中心化存储)?
    【解决方案2】:

    更新:React 16开始,官方支持portals

    Portals 提供了一种将子节点渲染到 DOM 节点的一流方法 存在于父组件的 DOM 层次结构之外。


    我不建议使用此解决方案,因为它使用了未记录的 React API。提供免责声明,这里是:

    class Portal extends React.Component {
      componentDidUpdate() {
        this._renderLayer();
      }
      
      componentDidMount() {
        this._renderLayer();
      }
      
      componentWillUnmount() {
        ReactDOM.unmountComponentAtNode(document.getElementById(this.props.container));
      }
    
      _renderLayer() {
        ReactDOM.unstable_renderSubtreeIntoContainer(this, this.props.children, document.getElementById(this.props.container));
      }
      render() {
        return null;
      }
    }
    
    class Y extends React.Component {
      render() {
        return <div>Y</div>;
      }
    }
    
    class X extends React.Component {
      render() {
        return (
          <div> 
            X
            <Portal container="Y">
              <Y />
            </Portal>
          </div>
        );
      }
    }
    
    ReactDOM.render(<X/>, document.getElementById('X'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    <div id='X'></div>
    <div id='Y'></div>

    【讨论】:

    • 嗨,我正在使用portal 解决这个问题,在容器中,我发送container={() =&gt; document.querySelector( 'body' )},它给了我以下错误:React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method
    • 嗨,它成功了。谢谢。我写错了import 声明
    • 如果您不需要访问上下文,您也许可以使用普通的React.render() 而不是危险的ReactDOM.unstable_renderSubtreeIntoContainer()
    猜你喜欢
    • 1970-01-01
    • 2019-09-24
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 2019-03-07
    • 2017-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多