Note: render is deprecated as of React 18

Let use first look at the signatures of both the methods.

render(element, container[, callback]);
createPortal(element, container);

Both the methods takes the element to render and the container where the element should be placed in the dom. Both does the job well.

This got me wondering what is the difference between the two:

  1. Even though the element is place outside the regular dom tree, in case of createPortal the child still lies within the parents component. The parent of the element rendered using createPortal can handle all the events hapenning on the child. That is, the events are bubbled back to the parent in case of createPortal.
  2. The other difference that sets createPortal apart from render is access to the same context as the parent. Many libraries like redux rely heavily on context and using the render method will break the child out of the context tree and makes it inaccessible. Where as the same doesn’t happen with createPortal.
//event bubbling example
import { render, createPortal } from "react-dom";
 
import React from "react";
 
  
 
export default function App() {
 
  return (
 
    <div className="App">
 
      <div
 
        className="example1"
 
        onClick={() => {
 
          console.log("Example 1");
 
        }}
 
      >
 
        {render(<h1>Toolbar1</h1>, document.querySelector(".toolbar1"))}
 
        <div className="editor"></div>
 
      </div>
 
      <div
 
        className="example2"
 
        onClick={() => {
 
          console.log("Example 2");
 
        }}
 
      >
 
        {createPortal(<h1>Toolbar2</h1>, document.querySelector(".toolbar2"))}
 
        <div className="editor"></div>
 
      </div>
 
    </div>
 
  );
 
}

In the code above there are two h1 elements, one rendered using render and the other using createPortal. Each of the elements are enclosed within a parent div with a onClick handler.

  • In case of createPortal(Toolbar2), when the click happens on the h1 element, as mentioned above the event is bubbled to the parent and triggers the onClick handler and prints Example 2 onto the console.
  • In case of render(Toolbar1), the click on the h1 element doesn’t bubble back to the parent div hence nothing is printed onto the console.