Creating a Reusable Modal Component With Portals in React

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MyrinNew
    Senior Member
    • Feb 2024
    • 5175

    #1

    Creating a Reusable Modal Component With Portals in React

    Creating a Reusable Modal Component With Portals in React

    Modals are a common UI pattern, but rendering them outside the main DOM tree can prevent styling and focus issues. This is where React Portals come in. In this tutorial, you'll learn to create a flexible, reusable modal component using portals.


    Step 1: Set Up Your Project

    Start with a React project using Create React App or Vite. We'll create a modal component that uses ReactDOM.createPortal to render outside the app root.


    Step 2: Create the Modal Component

    Inside components/Modal.js:



    import ReactDOM from "react-dom";

    function Modal({ isOpen, onClose, children }) {
    if (!isOpen) return null;

    return ReactDOM.createPortal(


    onClick={onClose}
    className="absolute top-2 right-2 text-gray-600 hover:text-black"
    >


    {children}



    ,
    document.getElementById("modal-root")
    );
    }

    export default Modal;


    Step 3: Add the Modal Root

    In your public/index.html, add a new div outside the root:











    Step 4: Use the Modal in Your App


    import { useState } from "react";
    import Modal from "./components/Modal";

    function App() {
    const [isOpen, setIsOpen] = useState(false);

    return (

    onClick={() => setIsOpen(true)}
    className="bg-blue-600 text-white px-4 py-2 rounded"
    >
    Open Modal


    setIsOpen(false)}>
    Reusable Modal

    This modal uses React portals to render outside the main DOM tree.




    );
    }

    export default App;


    Conclusion

    With React portals, you can build modals that behave correctly across your app. This pattern also scales well when you need tooltips, dropdowns, or any layered UI components.


    If this post helped you, consider supporting me: buymeacoffee.com/hexshift




    More...
Working...