【React】useStateを利用しゲーム作成 #2(一覧画面〜画面遷移)

はじめに

この章ではゲーム一覧を表示し「react-router-dom」で画面遷移ができるようにしていきます。

インストール

必要なライブラリをnpmよりインストールしていきます。
プロジェクト配下で以下コマンドを実施していきます。

画面遷移するために「react-router-dom」をインストールします。

npm install react-router-dom

こちらは今回関係ありませんが、scssを利用しているためインストールします。

npm install sass

作成

この章では、ゲーム一覧とページのヘッダー部分を作成して画面遷移が行えるような状態を作成していきます。

ヘッダー

シンプルな以下を作成していきます。
ホームを選択するたゲーム一覧画面へ戻るようにしていきます。

src配下に「components」フォルダを作成して、その中にHeader.jsxを作成します。
scssはsrc配下に「scss」フォルダを作成して、その中にHeader.module.scssを作成します。

import classes from "../scss/Header.module.scss";
import { Link } from "react-router-dom";

export const Header = () => {
  return (
    <header className={classes.header}>
      <p>ゲームアプリ</p>
      <nav>
        <ul>
          <li>
            <Link to="/">ホーム</Link>
          </li>
          <li>勝敗結果</li>
        </ul>
      </nav>
    </header>
  );
};
.header {
  display: flex;
  align-items: center;
  flex-direction: column;
  max-width: 100vw;
  margin: 0 auto;
  height: 15vh;
  background-color: rgb(198, 234, 201);
  nav {
    ul {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-wrap: wrap;
      list-style: none;
      padding: 0;
      margin: 0;
    }
    li {
      padding: 1vh 2vh;
    }
  }
}

import { Link } from “react-router-dom”;
react-router-domのLinkを利用して、画面遷移をします。
toの後ろにURLを記載します。後ほど設定するRouterとURLがマッチしたコンポーネントを返却するようになります。
※参考文献に公式ドキュメントを記載

一覧画面

ゲーム一覧を表示する画面(ホーム画面)を作成します。
ゲーム一覧の情報を定数(GAME_APP_LIST)として定義しています。
※画像を表示するようになっていますが、画像は適当に作成しpublic配下に格納しています。

こちらもヘッダー同様「Link」を利用して、画面遷移できるようにしています。

import { Link } from "react-router-dom";
import classes from "../scss/Home.module.scss";

const GAME_APP_LIST = [
  { name: "特定の数字を言ったら負け", link: "numbergame", sort: 2 },
  { name: "まるばつゲーム", link: "marubatsugame", sort: 1 },
];

const SortedGameAppList = GAME_APP_LIST.sort((a, b) => {
  return a.sort > b.sort ? -1 : 1;
});

export const Home = () => {
  return (
    <div className={classes.home}>
      <nav>
        <ul>
          {SortedGameAppList.map((gameApp) => {
            return (
              <li key={gameApp.sort}>
                <Link to={gameApp.link}>
                  <img src={`${gameApp.link}.png`} alt={gameApp.name} />
                  <p>{gameApp.name}</p>
                </Link>
              </li>
            );
          })}
        </ul>
      </nav>
    </div>
  );
};

画面遷移

画面遷移できるようにしていきます。
プロジェクト作成時に作成されている「index.js」と「App.js」を修正します。
※「NumberGame」のコンポーネントを利用していますが、次章で作成します。
 <React.StrictMode>はレンダーが多く走ってしまうのでコメントアウトしています。

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { Home } from "./components/Home";
import { NumberGame } from "./components/game/NumberGame";
import { ErrorPage } from "./components/ErrorPage";
import { createBrowserRouter, RouterProvider } from "react-router-dom";

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
    children: [
      {
        path: "/",
        element: <Home />,
      },
      {
        path: "numbergame",
        element: <NumberGame />,
      },
    ],
    errorElement: <ErrorPage />,
  },
]);

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  // <React.StrictMode>
  <RouterProvider router={router} />
  // </React.StrictMode>
);
import { Header } from "./components/Header";
import { Outlet } from "react-router-dom";

function App() {
  return (
    <>
      <Header />
      <Outlet />
    </>
  );
}

export default App;

createBrowserRouterでどのURLでどのコンポーネントを利用するかを紐づけています。
pathにURL、elementに対象コンポーネント、errorElementに対象URLが存在しない場合に表示するエラーページ様のコンポーネントを記載しています。前段で記載しましたが「Link to」で記載したURLとマッチするように記載しています。

childrenには、紐づけたコンポーネント内で利用するコンポーネントをURL毎に記載しています。
App.jsにて「Outlet」と記載している部分にchildrenで記載したコンポーネントが利用されます。今回の場合はヘッダーは全て共通で、URLによって「Home」コンポーネントを利用するのか、「NumberGame」コンポーネントを利用するのかが変わります。

RouterProviderによりcreateBrowserRouterで定義した内容が適用されます。

参考までにエラーページです。

import { useRouteError } from "react-router-dom";

export const ErrorPage = () => {
  const error = useRouteError();
  console.log(error);

  return (
    <div id="error-page">
      <h1>存在しないページです</h1>
      <p>
        <i>エラー内容:{error.statusText}</i>
      </p>
    </div>
  );
};

動作確認

ホーム画面

「特定の数字を言ったら負け」記載すると、URLが変わりヘッダーは同じですが利用するコンポーネントが変わります。(NumberGameコンポーネントは次章で作成)

ホーム画面に戻り、「まるばつゲーム」をクリックするとLinkで指定したURLに対応するコンポーネントを作成していないため、エラーページに遷移されます。

参考文献

Link v6.14.1
Tutorial v6.14.1
タイトルとURLをコピーしました