HomeReactReact Portals

React Portals

Portals is a feature which was added in React 16.

It lets you render children into DOM node outside of the parent component.

How to create Portal?

ReactDOM.createPortal(child,domNode)

where child can be any renderable React element such as fragment, strings or elements and domNode is DOM element.

What can we do with Portals?

We can make Modals, Tooltips or even opening a different window sharing same state as the component from which it is opened is also achievable using Portals.

So to see how to use Portal we will make a Modal using it.

Normally in our React App, we have HTML structure similar to

<html>
    <body>
        
    </body>
</html>

And inside this root element we render our whole App. This may seems unrelated to the topic but it will make sense just in a while.

Now continuing with Portal, below is the code for Portal component named as ModalPortal

class ModalPortal extends React.Component {
  constructor(props) {
    super(props);
    this.el = document.createElement("div");
  }

  componentDidMount() {
    this.el.classList.add("modal-block");
    document.body.appendChild(this.el);
  }

  componentWillUnmount() {
    document.body.removeChild(this.el);
  }

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

As you can see above, we are returning ReactDOM.createPortal(this.props.children, this.el) in the render method which will render ‘this.props.children’ which can be any React child inside ‘this.el’ element which is a div with class ‘modal-block’ which we have appended to body. Now we will open this portal on a click of button in our App component as shown below

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      showModal: false
    };
  }
  toggleModal = () =>
    this.setState(prevState => ({
      showModal: !prevState.showModal
    }));
  render() {
    const { showModal } = this.state;
    return (
      <React.Fragment>
        <button className="button is-success" onClick={this.toggleModal}>
          Show Modal
        </button>
        {showModal && (
          <ModalPortal>
            
              This is a Modal
              
                Close Modal
              
            
          </ModalPortal>
        )}
      </React.Fragment>
    );
  }
}

ReactDOM.render(<App />, document.querySelector("#root"));

When we will click on Show Modal button it will open a modal and HTML structure will be changed to below

<html>
    <body>
        
        
    </body>
</html>

Using Portals we are able to render something outside our root div and we can also close the modal from modal-block itself as same state is being shared between App component and ModalPortal component even when ‘modal-block’ div is not part of the App component hierarchy.

You can checkout the demo for modal implementaion using portal from the link given below

Codepen link : https://codepen.io/bhavya2995/full/xmLXPL

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: