🔧 Build a complete Modal Component with React Hooks 🌈
Victor de la Fouchardière
Posted on June 24, 2020
Hi guys !
Last week, we talked about 5 Customs React Hooks ! Many of you have shared this article. So this week, let's continue with React and the implementation of a Modal component without installing any packages!
A Modal component from scratch
Before starting, here are the elements we will use during this tutorial:
- React Hooks
- Portals from ReactDOM
- A little bit of CSS
Let's start with our modal.jsx
(or modal.js
) file !
Our component:
Let's start with the basics: the creation of our function component. The goal is to include any content to the modal and to manage the opening and closing of the component.
Secondly, what we want is a modal that is independent of our application. We don't want to have any z-index
concerns in css or any overflow
concerns. So let's insert this component into a different location in the DOM. But how?
Let's introduce the Portals from ReactDOM !
Portals provide a way to render children in a DOM node that exists outside of the DOM component hierarchy, that is, outside of the #root
or #app
div of your React application.
First, let's add a new div to our html
and give it a 'modal-app' ID. React does not create a new div, but displays the children in that modal-app
div.
Note that the #modal-app
can be any valid element of the DOM (div
, section
, span
...), regardless of its position.
And for our component to be inserted in this #modal-app
div, let's use the createPortal()
method offered by ReactDOM.
Even though a portal can be anywhere in the DOM tree, it behaves like a normal React child in every other way. Features like context work exactly the same regardless of whether the child is a portal, as the portal still exists in the React tree regardless of position in the DOM tree.
Source : Portals - React
So let's include this method for our component like this:
Open the Modal
Logically, it will be the parent component that will ask the modal to open. But how could we proceed?
First of all, let's add a local state to our Modal component in order to know if the modal is open or not.
useState
allows us to create our state with a boolean value. A defaultOpened
prop will tell us if we want to open the modal directly on create. false
is the default value.
- isOpen
true
=== Modal opened - isOpen
false
=== Modal closed
We use the conditionally rendering with the JavaScript conditional operator.
Then, in order for the parent to change this local state, you'll have to call up the "refs".
This is where useRef, useImperativeHandle and forwardRef come in.
To call setIsOpen
from the parent component, we need to attach a reference to our Modal.
-
useRef
is used to attach a reference to our modal. -
forwardRef
is used to forward the reference to the Modal component. -
useImperativeHandle
is used to expose methods to the parent component.
Close the Modal
Then, there are several ways to leave a modal.
- By clicking outside the content of the modal.
- By using the small cross (x) of our content.
- By using the ESCAP key of the keyboard.
First, let's capture the keydown
event and check if the user use the ESCAP key of his keyboard.
useEffect
allowing us to create a listener on the keydown
event ONLY if the modal is open. If the user uses the ESCAP key on his keyboard, then the modal closes.
The result is:
The CSS !
You can find the css code here.
Usage
- Demo: https://react-modal.viclafouch.vercel.app
- Source code: https://gist.github.com/viclafouch/6ee36b2cb7d28484d20f05e68b3433f9
Voilaaa ! Feel free to add your own modifications !
Cheers
Posted on June 24, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.