はじめに
この章ではゲーム一覧を表示し「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に対応するコンポーネントを作成していないため、エラーページに遷移されます。