HTML5のdialog要素を使って汎用的なReactモーダルコンポーネントを作る

2023年2月6日月曜日

react

t f B! P L

HTML5で追加された <dialog> タグを使って、汎用的に使える Reactのモーダルコンポーネントを作ってみる。

dialogタグのブラウザサポート

HTMLの<dialog> タグは、以前は Safari などの一部のブラウザでサポートされていませんでしたが、現在はメジャーなブラウザ全てでサポートされています。

enter image description here

コード

モーダルダイアログのコンポーネント

ModalDialog という名前で、ダイアログ部品を作る。

import React, { useCallback, useEffect, useRef } from 'react'

/**
 * モーダルダイアログ
 */
function ModalDialog({
  onClose,
  open,
  children,
}: ModalDialogProp): JSX.Element {
  const ref = useRef<HTMLDialogElement>(null)

  useEffect(() => {
    console.log(open)
    if (open && !ref.current?.open) {
      ref.current?.showModal()  //表示
    } else if (!open && ref.current?.open) {
      ref.current?.close()      //閉じる
    }
  }, [open])

  // 閉じるボタンクリック時の処理
  const handleClose = useCallback(
    () => ref.current?.close(),
    [ref],
  )
  
  return (
    <dialog ref={ref} onClose={onClose ?? (() => {})}>
      <p>
        {children}
      </p>
      <div>
        <button onClick={handleClose}>閉じる</button>
      </div>
    </dialog>
  )
}

/**
 * プロパティ
 */
 interface ModalDialogProp {
  /**
   * ダイアログクローズ時のイベント
   */
  onClose: () => void
  /**
   * ダイアログ表示状態(trueを設定するとダイアログが表示される)
   */
  open: boolean
  /**
   * ダイアログに表示するコンテンツ
   */
  children?: React.ReactNode
}

export default ModalDialog

使用方法


function Index() {

  const [open, setOpen] = useState(true)
  return (
    <div>
      <button onClick={() => setOpen(true)}>open</button>
      <ModalDialog open={open} onClose={() => {
        setOpen(false)
      }}>
        <div>
          ダイアログの中身です
        </div>
      </ModalDialog>
    </div>
  )
}

■実行結果

enter image description here

スポンサーリンク
スポンサーリンク

このブログを検索

Profile

自分の写真
Webアプリエンジニア。 日々新しい技術を追い求めてブログでアウトプットしています。
プロフィール画像は、猫村ゆゆこ様に書いてもらいました。

仕事募集もしていたり、していなかったり。

QooQ