Build a simple responsive modal with React and JSS (updated with Hooks).

It’s been over than 2 years from the original version of this article and both React and JSS API had some great improvements. This new article covers the same topic of the original one, using some of these new great features.

Sergio Pedercini
4 min readDec 16, 2019

The intent of this tutorial is to build a simple but extensible Modal Window component, with these key features:

  • responsive: full width on small devices, fixed width on bigger ones;
  • accepting every kind of content: html, images or others React components;
  • three way to close the modal: using the ESC key, clicking outside the window, clicking on a dedicated close “X” button.

To style our component, we’ll use JSS, a high performance CSS abstraction written in Javascript, that promise us some essential benefits:

  • scoped selectors with unique generated classname, no need to use ridiculous naming conventions like .block__elem--size-big (any reference to BEM is entirely coincidental 😉)
  • one stylesheet for each component, mounted in runtime with the component itself;

Before starting.

If you’re in a hurry, you can play with the finished version of this tutorial in CodeSandbox: https://codesandbox.io/s/react-simple-modal-20-ycqug
Otherwise keep reading!

STEP 1: creation of modal component.

To create the modal I decided to use two components:

  1. Modal.js will render the modal itself, with its stylesheet JSS file ModalStyles.js
  2. SimpleModal.js will render the modal opener button, and it will manage the visibility of the modal with its own state.

Modal.js: the rendered markup.

The html (JSX) markup is really simple, basically 3 elements: the main wrapper .modalOverlay contains the modal window .modal and the close button .closeButton. The modal window accepts {children} as prop, so we can assign to this component every kind of content.

The returned JSX markup.
A simulation of the modal. You can easily change the appearance with some line of JSS (CSS in JS).

Modal.js: the close action.

As clarified at the beginning, this component wont manage its visibility, this means that by itself it will be always visible. We’ll manage the visibility from its parent component SimpleModal.js.

However Modal.js contains some elements that if clicked, they are being able to close itself (e.g.: .closeButton). How is it possible to manage the visibility from the within the component, if we just said that the visibility is managed from the wrapper SimpleModal.js? The answer is really simple, SimpleModal.js will pass a close function as prop to Modal.js, in this way Modal.js can manage its visibility using SimpleModal.js own state.

Figured this out, we need to invoke the close function (i called it onCloseRequest) in these three events:

  1. clicking on the close button (the X on top right of the modal window);
  2. pressing ESC key;
  3. clicking outside the modal window.

1. Close the modal clicking on close button (the X on top right of the modal window)

It’s very simple: we call the onCloseRequest function on onClick event on .closeButton.

Managing the ESC click and the outside click events.

To manage these two events we need to listen to the keyboard key press and to the mouse click respectively. To do this we can add two listener on component mounting (and remove them on unmounting, to avoid duplicated events):

  • window.addEventListener('keyup') for keyboard key press.
  • document.addEventListener('click') for mouse click;

2. Close the modal clicking on ESC keyboad key.

If 'keyup' event is invoked, the handleKeyUp() function checks which is the pressed key, and if it matches, it calls the onCloseRequest() to close the modal (27 is the code for ESC key).

3. Close the modal clicking outside the modal window.

If 'click' event is invoked, the handleOutsideClick() function checks which DOM element was clicked. If the clicked element (e.target) is different from the modal window, this means that something outside it was clicked, so che can call the onCloseRequest() function to close the modal.

The complete component:

Let’s put all together to see the complete component file Modal.js.

The style

Now let’s look at the style file ModalStyles.js.
We’ll use a flex-box to center in the page the modal window vertically and horizontally, adding a keyframe animation to show it with a fade-in effect.

As you can see, JSS is nothing but a javascript object, where you have to declare all the css properties you need, converting their name with a camelcase convention to avoid the use of javascript minus (-) operator, e.g.: background-color => backgroundColor. Simple, isn’t it?

STEP 2: creation of the launcher component.

Now that our modal is ready, we need to build the launcher component. This component will take care of:

  • displaying a button or a link that opens the modal;
  • managing the visibility of the modal with its own state.

SimpleModal.js

In this component:

  1. we manage visibility state var showModal using useState React hook.
  2. if the user clicks on .modalButton, the setShowModal() function change the value of showModal state var to true
  3. if showModal is true we will show the <Modal /> component.

Putting all together.

Here you can see the complete example hosted on CodeSandbox.
Open in CodeSandbox

Thanks for reading, if you like this post please give it some claps and follow me to stay tuned for more stories and tutorials.

--

--