🍆

React-MenuをNext.jsで使うとき、サブメニューのタップ領域広げる(ページ遷移させたい時に活用)

2022/05/19に公開

React-Menuは小さなドロップダウン形式でメニューを表示できて大変便利です。

しかし、Next.jsで next/link を使おうとするとタップ領域に悩まされることもあるのではないでしょうか。

何もカスタマイズ無しで React-Menu が用意してくれてるスタイルをそのままに、Next.jsに適したページ遷移を実装してみましょう。

何が問題なのか?

import Link from 'next/link'

~

      <Menu menuButton={<MenuButton>メニューを開く</MenuButton>}>
        <MenuItem>
	  <Link href="/profile"><a>プロフィール</a></Link>
        </MenuItem>
      </Menu>

上記の実装では、

タップ領域はたったこれだけです。それ以外の余白箇所をタップしてもメニューが閉じるだけで、ページ遷移は行われません。

これをほとんど手を加えずに

これだけのタップ領域を確保するというのがゴールです。

結論

import { Menu, MenuItem, MenuButton } from '@szhsin/react-menu'
import { useRouter } from 'next/router'

const MyMenu = () => {
  const router = useRouter()

  return (
    <>
      <Menu menuButton={<MenuButton>メニューを開く</MenuButton>}>
        <MenuItem
          href="/profile"
          onClick={(e) => {
            e.syntheticEvent.preventDefault()
            router.push('/profile')
          }}
        >
          プロフィール
        </MenuItem>
        <MenuItem
          href="/api/auth/logout"
          onClick={(e) => {
            e.syntheticEvent.preventDefault()
            router.push('/api/auth/logout')
          }}
        >
          ログアウト
        </MenuItem>
      </Menu>
    </>
  )
}

onClickでイベントを発火し、
e.syntheticEvent.preventDefault() で通常のaタグのページ遷移を無効化し、
router.push() で Next.js が提供するページ遷移機能を実行するだけです。

単純な内容すぎて自己解決する人が多いためか、ネット上にこの情報が日本語で書かれているものがありませんでしたので、Zennに情報を残しておきました。確実に需要のある組み合わせだと思いますので、誰かの参考になれば幸いです。

React-Menuの公式サンプル: https://codesandbox.io/s/react-menu-react-router-example-dw4ku?file=/App.js

Discussion