Another way to create modals in react using the HTML dialog element
Tags: javascript, react
Published: 2022-10-25 08:00:00

## Introduction

Modals are a frequent UI element in our applications, in fact, I would say all the applications I have coded have some sort of modals on them.


![Modal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yvf5zfdzs5xwzoxpennm.png)



And when it comes to how to code them, we usually tend to use a UI
element (Bootstrap, Material UI, etc.) or develop our own implementation
in plain React, but did you know that there's a standard HTML element
called `dialog` to display modals?

## Why use the standard dialog element

Using the standard `dialog` element gives us several advantages over
doing our own implementation, advantages like:

- It's widely available (**92% of browsers support it at the moment**)


![Can I Useit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eei670mdpy976e1cbxzt.png)



- accessibility out of the box
 
This element already implements the most basic fundamental of accessibility for HTML dialogs
- standard HTML element 

Which mean that this element is not going away anytime soon, thus making our application a bit more future-proof
- less code 

Because we won't need to use the `aria-*` properties anymore, and also we don't need custom logic to render the modal outside the root component by using a `React.createPortal`

## Using dialog in your application


### Adding the dialog element to our component

In our React component, we just need to add a `dialog` element with the content we want

``` html
<dialog>
  <form method="dialog">
    <section>
      <label htmlFor="name">Name: </label>
      <input name="name" placeholder="Type your name" />
    </section>
    <section>
      <label htmlFor="email">Email: </label>
      <input name="email" placeholder="Type your email" />
    </section>
    <menu>
      <button id="cancel">
        Cancel
      </button>
      <button type="submit">Submit</button>
    </menu>
  </form>
</dialog>
```

- `method="dialog"`

  Basically tells our application that when the form gets submitted, the modal needs to be close automatically

### Accessing the dialog element on React

To do this, we will use the `useRef` hook

``` javascript
import React, { useRef } from "react";

function App() {
  const dialogRef = useRef();


  return (
      <dialog ref={dialogRef}>
          {/*...dialog content...*/}
      </dialog>
  )
}
```

### Add a button to show the modal

Let's add a `button` in our React component that once is called it will call the `showModal` function to open the modal

``` javascript
import React, { useRef } from "react";

function App() {
  const dialogRef = useRef();

  const showModal = () => {
    dialogRef.current.showModal();
  }

  return (
      <>
        <dialog ref={dialogRef}>
            {/*...dialog content...*/}
        </dialog>

        <button onClick={showModal}>Show Modal</button>
      </>
  )
```

### Handling form submit

Now the only things left is to handle the `onSubmit` event, so let's create a new function on the React Component to handle and get all the values from the form inside the modal

``` javascript
const onSubmit = (e) => {
  console.log({
    name: e.target.name.value,
    email: e.target.email.value
  })
}
```

## Final code

Let's add a function to close the modal and that will be the final code

``` javascript
import React, { useRef } from "react";

function App() {
  const dialogRef = useRef();

  const openModal = () => {
    dialogRef.current.showModal();
  };

  const onCancel = () => {
    dialogRef.current.close();
  };

  const onSubmit = (e) => {
    console.log({
      name: e.target.name.value,
      email: e.target.email.value,
    });
  };

  return (
    <>
      <dialog ref={dialogRef}>
        <form method="dialog" onSubmit={onSubmit}>
          <section>
            <label htmlFor="name">Name: </label>
            <input name="name" placeholder="Type your name" />
          </section>
          <section>
            <label htmlFor="email">Email: </label>
            <input name="email" placeholder="Type your email" />
          </section>
          <menu>
            <button onClick={onCancel}>Cancel</button>
            <button type="submit">Confirm</button>
          </menu>
        </form>
      </dialog>

      <button onClick={openModal}>Show Modal</button>
    </>
  );
}

export default App;
```

### Styling

To style our dialog we can use normal CSS properties, the only relevant and special thing is that if you want to change the background behind the modal you can use the pseudo-element `::backdrop`, example:

``` css
dialog::backdrop {
  background: rgba(0, 0, 0, 0.7);
}
```

## Polyfill

If you want to support browsers like Internet Explorer or old versions of Chrome, you will need to add this polyfill to your page:
<https://github.com/GoogleChrome/dialog-polyfill>