React MUI: Drawer と react-router-dom による画面遷移

スポンサーリンク

React MUI の Drawer にリンクを設定し、画面遷移する機能を紹介します。ダウンロード可能なサンプルもありますので、是非活用してください。

MUI と react-router-dom を組み合わせて実現しています。

動作イメージ

初期表示状態です。アプリケーションのルートページでは、画面中央に「Top」ページが表示されています。

画面左側の Drawer メニューにある、Page1 をクリックすると、画面中央に「Page1」ページが表示されます。

注目ポイント

アプリケーションの大まかな構造は、次の様になっています。注目していただきたいポイントは、react-router-dom の BrowserRouter の中に、リンクと、リンクに対応するルーティング情報がセットで配置されているところです。これら情報を BrowserRouter の外に配置してしまうと、エラーとなってしまい、ルーティングが動作しません。

下記は、アプリケーションの構造の概略を示します。(詳細な実装コードはこの後に示します。)

<Box>
  <AppBar (タイトルバー)></AppBar>
  <BrowserRouter>
    <Drawer>
      <List>
        <ListItem (リンク)></ListItem>
        <ListItem (リンク)></ListItem>
        <ListItem (リンク)></ListItem>
      </List>
    </Drawer>
    <Box>
      <Routes>
        <Route (ルーティング情報)/>
        <Route (ルーティング情報)/>
        <Route (ルーティング情報)/>
      </Routes>
    </Box>
  </BrowserRouter>
</Box>

実装コード

下記、MUI Drawer と react-router-dom に関連する実装コードとなります。

import React from "react";
import {
  Box,
  CssBaseline,
  AppBar,
  Toolbar,
  Typography,
  Drawer,
  Divider,
  List,
  ListItem,
  ListItemText,
} from "@mui/material";
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
import Top from "./pages/Top";
import Page1 from "./pages/Page1";
import Page2 from "./pages/Page2";

const drawerWidth = 240;

function App() {
  return (
    <Box sx={{ display: "flex" }}>
      <CssBaseline />
      <AppBar
        position="fixed"
        sx={{ width: `calc(100% - ${drawerWidth}px)`, ml: `${drawerWidth}px` }}
      >
        <Toolbar>
          <Typography variant="h6" noWrap component="div">
            MUI Drawer + react-router-dom Demo
          </Typography>
        </Toolbar>
      </AppBar>
      <BrowserRouter>
        <Drawer
          sx={{
            width: drawerWidth,
            flexShrink: 0,
            "& .MuiDrawer-paper": {
              width: drawerWidth,
              boxSizing: "border-box",
            },
          }}
          variant="permanent"
          anchor="left"
        >
          <Toolbar />
          <Divider />
          <List>
            <ListItem button key="top" component={Link} to={"/"}>
              <ListItemText primary="Top" />
            </ListItem>
            <ListItem button key="page1" component={Link} to={"/page1"}>
              <ListItemText primary="Page1" />
            </ListItem>
            <ListItem button key="page2" component={Link} to={"/page2"}>
              <ListItemText primary="Page2" />
            </ListItem>
          </List>
        </Drawer>
        <Box
          component="main"
          sx={{ flexGrow: 1, bgcolor: "background.default", p: 3 }}
        >
          <Toolbar />
          <>
            <Routes>
              <Route index element={<Top />} />
              <Route path="/" element={<Top />} />
              <Route path="page1" element={<Page1 />} />
              <Route path="page2" element={<Page2 />} />
            </Routes>
          </>
        </Box>
      </BrowserRouter>
    </Box>
  );
}

export default App;

サンプル

コメント

タイトルとURLをコピーしました