React開発入門② 〜画面遷移を学ぶ（Router)〜

## 目的
React上でのパスを指定した画面遷移の方法ができるようになる。

### 成果物のイメージ

【画面の数】
画面の遷移を学習するため、トップページとタイムレコーダーの２画面を作成します。

【画面遷移方法】
・トップページ→タイムレコーダー画面
トップページの『タイムレコーダー』をクリックするとタイムレコーダー画面に移行する。

## 遷移先のページコンポーネントを作る。
当たり前の話ですが、まずは遷移させるための画面を作らなければいけません。

まずは、プロジェクト内のsrc直下に移動し、pagesフォルダを作成してください。
作成が完了したら、その中にHome.jsxとPunchTimeClock.jsxを作成しましょう。
Home.jsxの中身は以下となります。
```Home.jsx
import { Link } from "react-router-dom"

export const Home = () => {
    return (
    <>  
        <h2>トップページ</h2>
        <nav>
            <ul>
                <li><Link to="/">トップページ</Link></li>
                <li><Link to="/punchtimeclock">タイムレコーダー</Link></li>     
            </ul>
        </nav>
    </>
    )
}
```
:::note
htmlではリンク先遷移には\<a href=>を使うのが一般的かと思いますが、reactでは\<Link to=>を使用します。

また、javascriptにはlocation.href =
遷移先パスという遷移方法もありますがこれもあまり使わない方がいいみたいです。
:::
PunchTimeClock.jsxは以下となります。
```PunchTimeClock.jsx
export const PunchTimeClock = () =>{
    return (
        <>
            <h2>タイムレコーダー</h2>
        </>
    );
};
```
:::note warn
外部コンポーネント化する際には export const を付けるようにしてください。
これがなければ外部から呼び出す時に　not findエラーが発生します。

また、外部呼出しされる関数コンポーネントの先頭は必ず大文字で始まる必要があります。
:::
コンポーネントの中身がないと遷移しているか分からないのでテスト用に簡易的なHTMLを返すようにしておきました。

## App.jsにパスと遷移先コンポーネントを紐づけるRouterを記載する。
Reactでは、ページ遷移をreact-router-domモジュール内のRouter,Routes,Routeを用いて定義します。
react-router-domをインストールしましょう。


次に、App.js内で先ほど定義した外部コンポーネントとreact-router-domのモジュールが使用できるようにimportさせましょう。

```App.js
import { BrowserRouter as Router, Routes, Route, Link} from "react-router-dom";
import { Home } from './Home';
import { PunchTimeClock } from './PunchTimeClock'
```

また、デフォルトのApp.jsにApp.cssのimport文があると思いますが、見た目が変わってややこしくなるためコメントアウトか削除しておいてください。

次にApp関数内にRouterを書いていきます。
```App.js
const App = () => {
  return (
    <Router>
      <div className="App">
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/punchtimeclock" element={<PunchTimeClock />} />
        </Routes>
      </div>
    </Router>
  );
}
```
ルート定義の構文は
\<Route path = パス名 element={遷移先コンポーネント} />
となります。
\<Route exact path="/" element={\<Home />} />
上の例でいうと、ルートのパスにHomeコンポーネントを表示することになります。

:::note
余談ですが、react-router-app最新バージョンで完全一致がデフォルトになっているのでexactの記述は現在不要です。(動作確認済み)
部分一致を実現したい場合はpathの末尾に*を追加して対応します。(後述)
:::

では、ブラウザに戻り動作確認をしてみましょう。
![スクリーンショット 2024-10-17 101952.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/ad68e94b-0b53-ded4-2f4c-e92731edcf51.png)
↑トップページはこのようになっているはずです。

『トップページ』リンクをクリックして下さい。
遷移先はトップページ（今いるページと同じ）なので変わっていなければ成功しています。

次に、『タイムレコーダー』リンクをクリックして下さい。
![スクリーンショット 2024-10-17 114645.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/79e05fd7-ec70-f16f-1263-a9a76a1f7117.png)

↑URLをみると/punchtimeclockに遷移しており、PunchTimeClockコンポーネントのhtmlが出力されています。


## 404ページを作成する
404ページも作成しておきましょう。
ユーザーが存在しないパスを指定してしまったときなどに『そんなページはないぞ！』と知らせる画面となります。

```App.js
const App = () => {
  return (
    <Router>
      <div className="App">
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/punchtimeclock" element={<PunchTimeClock />} />
          <Route path="/*" element={<html><h2>404 Not Found</h2></html>} />
        </Routes>
      </div>
    </Router>
  );
}
```
\<Route path="/*" element={\<html>\<h2>404 Not Found\</h2>\</html>} />
Routeに上記のパスを追加しました。element要素にはhtmlタグを使ってhtmlを直接埋め込んでいます。
上のパスを全部評価した後で該当しなかった場合はすべて404 Not Foundを表示するという意味です。

試しにURLに適当なパスを打ち込んで確かめてみましょう。
![スクリーンショット 2024-10-15 101601.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/627abf33-f0c4-f4ab-02b1-040b90f32725.png)

しっかりと404 Not Foundページが表示されています。

## 次回
タイムレコーダー画面の実装をしつつ、ボタンとダイアログ(モーダルウィンドウ)、さらにリアルタイムな時刻取得を学びます。