Issue when implementing ReactDOM.createPortal (react 16 feature)

1.3k Views Asked by At

For the sake of clarification, let's say I have 3 components: <Child>, <Parent>, <GrandParent>

I am trying to render <Child> within <GrandParent>, without rendering <Parent> (from which <Child> is called).

parent.js

class Parent extends Component {
  ...
  componentDidMount() {
    return (
      <Route ... component={ Child } />
    );
  }

  render() {
  // the <Route> element is rendered here
  }
}

When clicking on the link within <Parent>, I want <Parent> to unmount and <Child> to render within <GrandParent>, which is what React new feature 'Portal' should achieve.

From the doc, this how it should be implemented:

ReactDOM.createPortal(componentToRender, elementToRenderInto);
// Hence in my case:
ReactDOM.createPortal(<Child />, document.getElementById('grand-parent'));

But I am not sure how/where to use this piece of code. Everything I tried rendered <Child> next to <Parent>, which is not what I want. Tips/doc/examples on the subject is very much welcomed

1

There are 1 best solutions below

0
On

If I get it right, grandparent component has to obtain a reference to underlying DOM node and pass it down to parent, then parent renders a portal with child.

I guess this could be what you are trying to achieve:

class GrandParent extends React.Component {
  state = {};
  getRef = that => this.setState({ self: that });
  render() {
    return (
      <div ref={this.getRef} style={{}}>
        +
        <Parent parent={this.state.self}>
          <Child />
        </Parent>
        +
      </div>
    );
  }
}

class Parent extends React.Component {
  render() {
    if (this.props.parent)
      return createPortal(this.props.children, this.props.parent);
    return (
      <div>
        parent<Child />
      </div>
    );
  }
}

class Child extends React.Component {
  render() {
    return <div>child</div>;
  }
}

codesandbox