Reusable Modal Component using React Portals

Reusable Modal Component using React Portals

How to create a reusable modal component from scratch

By the end of this tutorial, we will have a modal component that can be used anywhere in a React Application. We can create a modal just by passing the children to the component.

CodeSandbox Implementation

React Portal

They’re cool for rendering UI outside of your current components. We are making a Modal component that shows a message to the user . It should always show up centered in the window. We put the portal higher up in the DOM outside of all out layouts, and render the modal component into it. Then when we want to use it, we just render a passing the message UI as a prop.

Creating the Modal Component

In index.html create a div with id modal, besides the root div. This is where we will render the modal.

Modal Styling

For basic styling, we’ll define some CSS rules. The #modal div will serve as the container for our modal content.

Create Modal.tsx file for the component. Write the boilerplate and props for the component.

We render the children in #modal div using document.getElementById(“modal”).

Using createPortal function we can pass the children and the Ref as arguments. So any children will get rendered inside the Modal Div using Ref. Thus we have a reusable component that can take in React Chiukldren and render as our modal.

return <>{createPortal(children, elRef?.current)}</>;

To close the modal, we listen to all clicks and toggle the state if it’s outside the child.
To avoid memory leaks, we have to return a cleanup function and remove our event listener for closing the modal.

Usage of Modal Component

You can import the modal component and create a Boolean State to open and close the Modal. Pass the children, state and closeModal function to the component. The component will mount the children inside the #modal id div.

You can find the complete TypeScript + React implementation in this CodeSandbox .

Lakshya Dhariwal

Leave a Reply

Your email address will not be published. Required fields are marked *