🐇

[React + Typescript + MUI] テキストナビゲーションの作り方

2024/11/29に公開

概要

React + Typescript + MUIを使ったテキストナビゲーションの作り方についてまとめました。
自分自身の勉強とアウトプットをすることによる知識の定着が狙いです。間違っている箇所があればご指摘をお願いします。

前提

React + Typescriptの環境が構築済みである

パッケージのインストール

react-router-dom

npm install react-router-dom

@mui/material

npm install @mui/material @emotion/react @emotion/styled

テキストナビゲーションを作る

テキストナビゲーションを作るには以下の手順で行います

  1. リストを作る
  2. リストにリンクを設定する

また、srcフォルダ以下に任意の名前でファイルを作ります(ここではLayouteTest.tsxにします)
なお、リスト部分はMUIを使い、リンク部分はreact-router-comを使います

リストを作る

リストを作るにはMUIのListListItemListItemButtonListItemTextを使います

基本的な概念

List: リスト全体のコンテナ
ListItem: リスト内の個々のアイテム
ListItemButton: ListItemをクリック可能にするコンポーネント
ListItemText: リストに表示するテキストのコンポーネント

リストのコード

リストを実装したファイルの全コードを掲載します。下記のリンクの設定はこのコードを元に変更しています。

src/LayouteTest.tsx
import React from 'react'
import { List, ListItem, ListItemButton, ListItemText } from '@mui/material'

const LayoutTest = () => {
  return (
    <div>
      <List>
        <ListItem disablePadding>
          <ListItemButton>
            <ListItemText primary="Home" />
          </ListItemButton>
        </ListItem>
        <ListItem disablePadding>
          <ListItemButton>
            <ListItemText primary="About" />
          </ListItemButton>
        </ListItem>
      </List>
    </div>
  )
}
export default LayoutTest

リストのポイント

  1. List: リスト全体のコンテナ
  2. disablePadding: ListItem の余白をなくすオプション(デフォルトは余白がある)
  3. ListItemButton: クリック可能なアイテムを作成
  4. ListItemText: テキストを簡単に表示

リストの補足

  • ListItemTextsecondaryオプションを設定するとprimaryより少し小さいテキストが表示される

ここまでで、クリックできる状態(ホバーするとカーソルが変わる)になります

リンクを設定する

リストにリンクを設定するにはreact-router-domLinkNavLinkのどちらかを使います。
Link: シンプルなリンクを設定する
NavLink: リンクの設定の他に、アクティブかどうかによりスタイルを切り替えられる

ナビゲーションで使うなら、選択しているアイテムのスタイルが変更できるNavLinkが便利そう

Linkの場合

ListItemLinkで囲み、toオプションで移動先を設定します

<Link to="/">
  <ListItem disablePadding>
    ...
  </ListItem>
</Link>

ListItemNavLinkで囲み,toオプションで移動先を設定する他に、デフォルトの関数でtoと現在のURLが一致するとtrueを返します。これによりアクティブ時と非アクティブ時のスタイルが設定できます。
下の例では、アクティブか非アクティブかにより適用するクラスを変更しています

<NavLink
  to="/" 
  className={({ isActive }) => (isActive ? 'active-link' : 'inactive-link')}
>
  <ListItem disablePadding>
    ...
  </ListItem>
</NavLink>

留意点や感想など

  • アイコン付きナビゲーションやmapを使ったリファクタリングもしたかったのですが長くなったので分割します
  • NavLinkListItemの順番(内外)を変更してListItemを外側にすると、クリックできる箇所がテキスト部分だけになりました。
  • 記事にまとめると時間はかかりますが理解が進むので最近はまっています

Discussion