Home React React Portals: Creating a Dialog

React Portals: Creating a Dialog

In this tutorial, you are going to learn what react portals are and how to use them to spawn components anywhere on the DOM.

We will take a look at the example of a simple dialog component to grasp the concepts of portals and why they are useful.

What are react portals?

React portals allow us to place a component outside of the DOM-scope of its parent element. That way it is possible for a component to always have the same DOM-parent independent of its actual parent in the react tree.

Portals are created by using the react-dom createPortal method:

render() {
  return ReactDOM.createPortal(<Component />, document.body);

The first argument is the component that should be placed elsewhere. The second argument is the new parent DOM-node of the component.

You can import ReactDom from react-dom like so (I had to google that 😊):

import ReactDOM from 'react-dom'

Why to use portals?

Portals come in handy if you need to avoid restrictions imposed by the CSS styles of the parent element. For example, if the parent has the wrong z-index or prevents overflows.

If we wanted to place a dialog- or a tooltip-component inside of a button-component, but the button has its overflow-attribute set to ‘hidden’, we would not be able to see the dialog/tooltip.

With react portals we can still place our dialog anywhere in the react component tree and still attach it to the document body, avoiding all restrictions.

Event bubbling

Since the teleported component is no longer a child of its parent-components DOM-node, the parent would typically not receive bubbled-up events from that component.

Luckily, this is not an issue, because the teleported component is still a child of its parent in the react component tree. Therefore the react events are still bubbling properly.

Example: A modal dialog

Creating such a dialog component with portals is quite straight forward. The only difference from a regular component is the usage of the ReactDOM.createPortal method.

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import './Dialog.css'

export default class Dialog extends Component {
  renderDialog() {
    if (this.props.open) {
      return (
        <div className="background">
          <div className="dialog">{this.props.children}</div>

  render() {
    return ReactDOM.createPortal(this.renderDialog(), document.body)

In this case, we are using the renderDialog method to return the actual component of the class. This component is attached to the document-body using the ReactDOM.createPortal method.

The background is responsible for blurring out everything but the dialog. This is done by using a semi-transparent background color:

.background {
  width: 100%;
  height: 100%;
  position: absolute;
  background-color: rgba(0, 0, 0, 0.2);
  display: flex;
  justify-content: center;
  align-items: center;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;

The dialog itself has a white background and a nice drop-shadow:

.dialog {
  background-color: white;
  position: relative;
  height: 50%;
  width: 50%;
  box-shadow: 0 15px 30px 0 rgba(0, 0, 0, 0.11), 0 5px 15px 0 rgba(0, 0, 0, 0.08);
  padding: 32px;
  display: flex;
  flex-direction: column;
  overflow-y: auto;

The Dialog is then used in the App component like this:

import React, { Component } from 'react'
import './App.css'
import Dialog from './Dialog'

class App extends Component {
  constructor(props) {
    this.state = { isDialogOpen: false }

  render() {
    return (
      <div className="app">
        <div className="limitingDiv">
          <Dialog open={this.state.isDialogOpen}>
            <p>Lorem ipsum ...</p>
            <p>Duis autem ...</p>
            <div style={{ flex: 1 }} />
              onClick={() => this.setState({ isDialogOpen: false })}
          style={{ width: '50%' }}
          onClick={() =>
            this.setState({ isDialogOpen: !this.state.isDialogOpen })
          Open Dialog

export default App

To test the effect of the portal I’ve added a limitingDiv that has a set height and the overflow set to hidden. Without the portal, the dialog would not be visible.

.limitingDiv {
  height: 100px;
  overflow: hidden;
  position: relative;


In this tutorial, we learned how to use portals to change the location of a component on the DOM.

I hope you enjoyed this post.


Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

The Binary Search Algorithm in JavaScript

In this post, I'll compare linear search and binary search algorithms. You'll see pseudocode for each algorithm, along with examples and a...

JavaScript Callbacks, Promises, and Async Functions|Part 2

Introduction In part one of this tutorial, we learned the principles behind asynchronous programming and using callbacks. To review,...

JavaScript Callbacks, Promises, and Async Functions| Part 1

Introduction There is a lot of talk about asynchronous programming, but what exactly is the big deal? The big...

JavaScript Best Practices for Beginners

1. Use === Instead of == JavaScript utilizes two different kinds of equality operators: === | !== and == | != It is considered best practice to...

Recent Comments

Sathish Kumar Ramalingam on Angular 2 Admin LTE Theme Integration