Say Yes to Modals with the Dialog Tag!
Tags: react, javascript, programming, frontend
Published: 2023-05-03 12:30:13

Modal components are widely used in web development, but they often rely on a multitude of nested div elements, which can make the code less readable and harder to maintain. In this article, we'll explore an alternative approach using the HTML dialog tag that can help keep our code clean and efficient.

## Why Use the Dialog Tag?

Here are a few reasons why using the dialog tag can be beneficial for implementing modals:

- It comes with its own built-in backdrop and positioning, saving you time and effort.
- It's easy to style both the backdrop and the dialog itself.
- It has native methods for opening and closing the dialog, making it easy to implement with React.

## How to Use the Dialog Tag

Let's jump straight into the code and see how we can create a Modal component using the dialog tag:

## The Modal

```jsx
// Modal.jsx

const Modal = forwardRef(({ children, onClose }, ref) => {
  return (
    <dialog ref={ref}>
      <button onClick={onClose}>&times;</button>
      {children}
    </dialog>
  );
});
```

Here, we've created a Modal component that takes in two props: children, which represent the content of the modal, and onClose, which is a function that will be called when the user clicks on the close button. The forwardRef function is used to forward the ref to the dialog element.

Next, let's take a look at the useModal hook, which will be used to manage the state of the modal:

```jsx
// useModal.js

function useModal() {
  const ref = React.useRef(null);
  const onOpen = () => ref.current.showModal();

  const onClose = () => {
    ref.current.className = "close";
    setTimeout(() => {
      ref.current.close();
      ref.current.className = "";
    }, 400); // this value will matching your css animation timing
  };

  return { ref, onOpen, onClose };
}
```

Here, we've created a useModal hook that returns an object with three properties: ref, onOpen, and onClose. The ref is used to reference the dialog element created by the Modal component, and the onOpen and onClose functions are used to show and hide the modal respectively.

Finally, let's put everything together in our App component:

```jsx
// using the modal and the hook

export default function App() {
  const { ref, onOpen, onClose } = useModal();

  return (
    <div className="App">
      <button onClick={onOpen}>open modal</button>

      <Modal ref={ref} onClose={onClose}>
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
      </Modal>
    </div>
  );
}
```

Here, we've created an App component that renders a button that, when clicked, calls the onOpen function to open the modal. The Modal component is then rendered with the ref and onClose props.

You can easily customize the appearance of the modal to fit your needs. After adding some basic styles and animations I get something like this:

{% codesandbox https://codesandbox.io/embed/modal-with-dialog-sl1q32?fontsize=14&hidenavigation=1&theme=dark&view=preview %}

## Conclusion

Using the dialog tag can be a great way to simplify the implementation of modals in your React projects. By taking advantage of the built-in features of the dialog element, we can write cleaner and more efficient code, making our projects easier to maintain and debug. Give it a try in your next project and see the benefits for yourself!