Introduction to React.js Portals

React Portals provide a way to render components outside their normal DOM hierarchy. In React, components are usually rendered as part of their parent component’s DOM structure. However, there are situations where rendering a child component outside its parent DOM tree is necessary. This is where React Portals come in.


What is a Higher Order Component (HOC)?

A Higher Order Component is a function that takes a component and returns a new component. It allows you to separate concerns by extracting logic that can be shared across multiple components into a reusable function.

Portals allow you to render a child component into a different part of the DOM, outside of its usual parent-child relationship.


Why Use React Portals?

Portals are useful in scenarios where you need to bypass CSS styles of parent components or avoid z-index conflicts. For instance:
  • Modals and Dialogs: Modals often need to appear above other components, and portals can place them at the root level of the DOM to avoid issues with z-index.
  • Tooltips: To ensure tooltips render correctly and are not restricted by their parent component's layout.
  • Dropdowns: Dropdowns that need to render above other elements.
  • By rendering these components outside of their regular parent DOM hierarchy, you can manage them more effectively.


    How to Use React Portals

    React provides a method called ReactDOM.createPortal to create a portal. This method requires two arguments:

  • The child component you want to render.
  • The DOM node where you want to render the component
  • Syntax:

    				
    					ReactDOM.createPortal(child, container);
    
    				
    			
  • child: The JSX/React component you want to render.
  • container: The DOM element where you want to render the component

  • Example of Using React Portals

    Let’s create a simple modal using a portal. The modal will be rendered outside of the usual DOM tree.

    Step 1: Create the Modal Component

    				
    					import React from 'react';
    import ReactDOM from 'react-dom';
    
    function Modal({ children, onClose }) {
      return ReactDOM.createPortal(
        <div style={modalStyle}>
          <div style={modalContentStyle}>
            {children}
            <button onClick={onClose}>Close</button>
          </div>
        </div>,
        document.getElementById('modal-root') // Render to modal-root
      );
    }
    
    const modalStyle = {
      position: 'fixed',
      top: 0,
      left: 0,
      width: '100%',
      height: '100%',
      backgroundColor: 'rgba(0, 0, 0, 0.5)',
      display: 'flex',
      justifyContent: 'center',
      alignItems: 'center'
    };
    
    const modalContentStyle = {
      backgroundColor: 'white',
      padding: '20px',
      borderRadius: '8px'
    };
    
    export default Modal;
    
    				
    			
    Step 2: Use the Modal in the Main Component
    				
    					import React, { useState } from 'react';
    import Modal from './Modal';
    
    function App() {
      const [isModalOpen, setModalOpen] = useState(false);
    
      const openModal = () => setModalOpen(true);
      const closeModal = () => setModalOpen(false);
    
      return (
        <div>
          <h1>Welcome to the App</h1>
          <button onClick={openModal}>Open Modal</button>
          {isModalOpen && <Modal onClose={closeModal}>This is the modal content!</Modal>}
        </div>
      );
    }
    
    export default App;
    
    				
    			
    Step 3: Set Up the Portal Root in HTML
    In your public/index.html file, you need to add a dedicated element where the portal will render.
    				
    					<!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>React Portal Example</title>
    </head>
    <body>
      <div id="root"></div>
      <div id="modal-root"></div> 
    </body>
    </html>
    
    				
    			
    In this example, the modal will render into the modal-root div, which is separate from the main root div where the rest of your app is rendered.


    Benefits of Using React Portals

  • Avoiding z-index issues: By rendering elements outside their parent DOM tree, portals help prevent z-index conflicts that can occur with deeply nested components.

  • DOM Hierarchy Control: Portals enable you to separate the rendering logic of components like modals and tooltips, placing them in different parts of the DOM without affecting the existing structure.

  • Styling Flexibility: Since portals allow rendering outside the parent, components can avoid inheriting restrictive CSS styles from their ancestors, allowing better control over positioning and layout.


  • Event Bubbling and Portals

    One important aspect of portals is that they do not affect event bubbling. Events triggered within a portal still propagate through the DOM as if the portal component were rendered within the parent DOM hierarchy. This means that event listeners set on ancestor components will still capture events from portal components.

    For example, if a modal (rendered via a portal) triggers a click event, that event will still propagate through the normal React component hierarchy, allowing parent components to respond to it.


    When Not to Use Portals

    Portals should be used when you need to render content outside the regular component hierarchy. However, they are not necessary for all components. Here are some cases when not to use portals:

  • When the content is simple and fits naturally within the normal DOM flow.
  • When there’s no need for separate rendering (like regular UI components).

  • Conclusion

    React Portals provide a flexible way to render components outside their normal parent-child relationship in the DOM. This makes them ideal for UI elements like modals, tooltips, and dropdowns that need to be rendered on top of other elements or outside the usual DOM structure. By using ReactDOM.createPortal, you can maintain the logical hierarchy of your components while bypassing any layout, styling, or z-index issues caused by DOM nesting.
    ×