admin管理员组

文章数量:1025478

I have a ponent, say X which is rendered by my app and in the DOM-body. I have another ponent Y which is rendered by the ponent X but the ponent Y should be opened in full-screen. So, I need to render this in document.body rather inside ponent X even if X renders it.

React Components' structure is:

app
    -X
         -Y (in Full Screen)

the structure now should look like:

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

and the rendered flow should be :

app.body
    -X
-Y

and the DOM structure should be:

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

How can I do this. Also, I am using ES6 classes for making react-ponents.

I have a ponent, say X which is rendered by my app and in the DOM-body. I have another ponent Y which is rendered by the ponent X but the ponent Y should be opened in full-screen. So, I need to render this in document.body rather inside ponent X even if X renders it.

React Components' structure is:

app
    -X
         -Y (in Full Screen)

the structure now should look like:

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

and the rendered flow should be :

app.body
    -X
-Y

and the DOM structure should be:

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

How can I do this. Also, I am using ES6 classes for making react-ponents.

Share Improve this question edited Aug 24, 2016 at 12:42 Ajay Gaur asked Aug 24, 2016 at 12:37 Ajay GaurAjay Gaur 5,2807 gold badges40 silver badges63 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

UPDATE: Starting from React 16, there is official support for portals.

Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent ponent.


I wouldn't remend to use this solution as it is using an undocumented React API. Disclaimer provided, here it is:

class Portal extends React.Component {
  ponentDidUpdate() {
    this._renderLayer();
  }
  
  ponentDidMount() {
    this._renderLayer();
  }
  
  ponentWillUnmount() {
    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./ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='X'></div>
<div id='Y'></div>

Simply render each of your ponent in their own <div>:

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

And render each ponent separately:

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

I have a ponent, say X which is rendered by my app and in the DOM-body. I have another ponent Y which is rendered by the ponent X but the ponent Y should be opened in full-screen. So, I need to render this in document.body rather inside ponent X even if X renders it.

React Components' structure is:

app
    -X
         -Y (in Full Screen)

the structure now should look like:

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

and the rendered flow should be :

app.body
    -X
-Y

and the DOM structure should be:

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

How can I do this. Also, I am using ES6 classes for making react-ponents.

I have a ponent, say X which is rendered by my app and in the DOM-body. I have another ponent Y which is rendered by the ponent X but the ponent Y should be opened in full-screen. So, I need to render this in document.body rather inside ponent X even if X renders it.

React Components' structure is:

app
    -X
         -Y (in Full Screen)

the structure now should look like:

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

and the rendered flow should be :

app.body
    -X
-Y

and the DOM structure should be:

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

How can I do this. Also, I am using ES6 classes for making react-ponents.

Share Improve this question edited Aug 24, 2016 at 12:42 Ajay Gaur asked Aug 24, 2016 at 12:37 Ajay GaurAjay Gaur 5,2807 gold badges40 silver badges63 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

UPDATE: Starting from React 16, there is official support for portals.

Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent ponent.


I wouldn't remend to use this solution as it is using an undocumented React API. Disclaimer provided, here it is:

class Portal extends React.Component {
  ponentDidUpdate() {
    this._renderLayer();
  }
  
  ponentDidMount() {
    this._renderLayer();
  }
  
  ponentWillUnmount() {
    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./ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='X'></div>
<div id='Y'></div>

Simply render each of your ponent in their own <div>:

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

And render each ponent separately:

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

本文标签: