Modal with a Functional Component
Tags: react, hooks, modal
Published: 2021-02-09 17:32:21

---
title: Modal with a Functional Component
published: true
description: How to create a modal using hooks and functional components
tags: #react #hooks #modal
//cover_image: https://direct_url_to_image.jpg
---

Yes! yet another modal tutorial but there's a catch! This one attaches an event listener on a div container rather than the document or window. Let's see how:

1. We first create the basic Modal Functional component
```
import React, { useRef } from "react";

const Modal = ({ open, onClose, children }) => {
  const modalRef = useRef(null);

  return (
    open && (
      <div className="modal-overlay" ref={modalRef}>
        <div className="modal-content">{children}</div>
        <button className="close-btn" onClick={onClose}>
          Close
        </button>
      </div>
    )
  );
};

export default Modal;

```
2. We then attach our event listeners not to the `document`, or the `window` but to the `div` container for our Modal.
```
import React, { useCallback, useEffect, useRef } from "react";

const Modal = ({ open, onClose, children }) => {
  const modalRef = useRef(null);

  const handleKeyPress = useCallback(
    ({ keyCode }) => keyCode === 27 && onClose(),
    [onClose]
  );

  useEffect(() => {
    let target = modalRef && modalRef.current;
    if (target) {
      target.addEventListener("click", onClose);
      target.addEventListener("keydown", handleKeyPress);
    }

    return () => {
      if (target) {
        target.removeEventListener("click", onClose);
        target.removeEventListener("keydown", handleKeyPress);
      }
    };
  }, [modalRef, onClose, handleKeyPress]);

  return (
    open && (
      <div className="modal-overlay" ref={modalRef}>
        <div className="modal-content">{children}</div>
        <button className="close-btn" onClick={onClose}>
          Close
        </button>
      </div>
    )
  );
};

export default Modal;

```
3. We make sure to attach `tabIndex="0"` property on the container and focus on it as we attach the listeners. These are the two important steps to make the Modal close by pressing `Èsc` button.
```
import React, { useCallback, useEffect, useRef } from "react";

const Modal = ({ open, onClose, children }) => {
  const modalRef = useRef(null);

  const handleKeyPress = useCallback(
    ({ keyCode }) => keyCode === 27 && onClose(),
    [onClose]
  );

  useEffect(() => {
    let target = modalRef && modalRef.current;
    if (target) {
      modalRef.current.focus(); // important
      target.addEventListener("click", onClose);
      target.addEventListener("keydown", handleKeyPress);
    }

    return () => {
      if (target) {
        target.removeEventListener("click", onClose);
        target.removeEventListener("keydown", handleKeyPress);
      }
    };
  }, [modalRef, onClose, handleKeyPress]);

  // tabIndex on our div tag
  return (
    open && (
      <div tabIndex="0" className="modal-overlay" ref={modalRef}>
        <div className="modal-content">{children}</div>
        <button className="close-btn" onClick={onClose}>
          Close
        </button>
      </div>
    )
  );
};

export default Modal;

```

[Click here to see the Full Demo](https://codesandbox.io/s/react-fc-modal-8qqbv)