2025年5月24日土曜日

【第2回】React Routerで画面遷移を実装しよう!

✅ はじめに

こんにちは!このシリーズでは、React + Vite + TypeScript + MUIという現代的な技術スタックを使って、Webアプリを開発する方法をステップバイステップで解説していきます。

第2回となる今回は、React Routerを使って「複数のページを持つアプリケーション」を作成します。画面遷移やルーティングの仕組みを理解することで、より本格的なアプリ開発ができるようになります!

📦 使用する技術スタック

ツール バージョン 説明
React Router v6.x Reactアプリケーションのルーティングライブラリ
MUI v5.x マテリアルデザインベースのUIコンポーネント
TypeScript 5.x 型安全なJavaScript
Vite 5.x 高速な開発環境とビルドツール

🚀 実装手順

1. 必要なパッケージのインストール

npm install react-router-dom @mui/material @emotion/react @emotion/styled @fontsource/roboto

2. ページコンポーネントの作成

src/pages/Home.tsx

import { Container, Typography, Paper, Box } from '@mui/material';

const Home = () => {
  return (
    <Container maxWidth="md">
      <Paper elevation={3} sx={{ p: 4, mt: 4 }}>
        <Typography variant="h4" component="h1" gutterBottom>
          ホームページ
        </Typography>
        <Box sx={{ mt: 2 }}>
          <Typography variant="body1">
            このアプリケーションは、React Router v6を使用した
            シンプルなルーティングのデモンストレーションです。
          </Typography>
        </Box>
      </Paper>
    </Container>
  );
};

export default Home;

src/pages/About.tsx

import { Container, Typography, Paper, Box, List, ListItem, ListItemText } from '@mui/material';

const About = () => {
  return (
    <Container maxWidth="md">
      <Paper elevation={3} sx={{ p: 4, mt: 4 }}>
        <Typography variant="h4" component="h1" gutterBottom>
          このアプリについて
        </Typography>
        <Box sx={{ mt: 2 }}>
          <Typography variant="body1" paragraph>
            このアプリケーションは以下の技術スタックを使用しています:
          </Typography>
          <List>
            <ListItem>
              <ListItemText 
                primary="React + TypeScript" 
                secondary="型安全なコンポーネント開発"
              />
            </ListItem>
            <ListItem>
              <ListItemText 
                primary="React Router v6" 
                secondary="モダンなルーティング機能"
              />
            </ListItem>
            <ListItem>
              <ListItemText 
                primary="Material-UI (MUI)" 
                secondary="美しいUIコンポーネント"
              />
            </ListItem>
          </List>
        </Box>
      </Paper>
    </Container>
  );
};

export default About;

3. App.tsxでのルーティング設定

import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
import { 
  AppBar, 
  Toolbar, 
  Button, 
  Container, 
  ThemeProvider, 
  createTheme,
  Box,
  Typography
} from '@mui/material';
import Home from './pages/Home';
import About from './pages/About';

const theme = createTheme({
  typography: {
    fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
  },
});

function App() {
  return (
    <ThemeProvider theme={theme}>
      <BrowserRouter>
        <Box sx={{ flexGrow: 1 }}>
          <AppBar position="static">
            <Toolbar>
              <Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
                React Router Demo
              </Typography>
              <Button 
                color="inherit" 
                component={Link} 
                to="/"
                sx={{ mr: 2 }}
              >
                Home
              </Button>
              <Button 
                color="inherit" 
                component={Link} 
                to="/about"
              >
                About
              </Button>
            </Toolbar>
          </AppBar>
        </Box>

        <Container>
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/about" element={<About />} />
          </Routes>
        </Container>
      </BrowserRouter>
    </ThemeProvider>
  );
}

export default App;

🎯 主要なポイント

1. React Routerの基本概念

  • BrowserRouter: URLベースのルーティングを提供
  • Routes: ルート定義のコンテナ
  • Route: 個別のルートを定義
  • Link: ページ間のナビゲーション

2. MUIとの統合

  • AppBarによるナビゲーションバー
  • Containerによるレイアウト
  • Buttonコンポーネントとリンクの統合

3. 型安全性

  • TypeScriptによる型チェック
  • コンポーネントpropsの型定義

🔚 まとめ

このチュートリアルでは、React RouterとMUIを組み合わせて、モダンなナビゲーションを持つSPAを構築する方法を学びました。次回は、フォームの実装とバリデーションについて解説します。

📚 次回予告

【第3回】フォームの作成とバリデーション(MUI + React Hook Form)