/home/huy/everyday

everyday: Development Log

01.03.2022 - React/Render a component to any DOM node with React Portals

In React, you can mount a component into any DOM node instead of just the current parent component, with the help of ReactDOM.createPortal([content], [node] ).

It's very helpful when working with modal dialogs or tooltips.

For example, the following MooContainer component will create a portal in document.body, with the content is the MooContent component:

const MooContent = () => <div>Moooooo!</div>;
const MooContainer = () => {
  return ReactDOM.createPortal(<MooContent />, document.body);
};

Regardless of where we will mount MooContainer, the MooContent will always be rendered in body:

const App = () => {
  return <div>
    Hello
    <MooContainer />
  </div>;
};

Output:

<body>
  <div id="root">
    <div>Hello</div>
  </div>
  <div>Moooooo!</div>
</body>

Using this method, only the HTML structure of the document will be affected and there are no changes in terms of the React's component structure, so, the hierarchy of your component should still be:

 App
  ├─ div
  └─ MooContainer
      └─ MooContent

Event bubbling will respect this hierarchy, from MooContent to MooContainer then App.

Accessibility wise, since MooContent is rendered under document.body, keyboard navigation or screen reader's flow will also be affected by this HTML structure, so make sure you handled them properly by yourself.

Read more