今回は、Reactアプリケーションにreact-router-domを導入して画面遷移を実装していきます。
Reactのアプリケーションは、SPA(シングルページアプリケーション)と言って画面遷移の仕組みが特殊なので、その辺も理解しておくと良いと思います。
今回は「Material UIを使ってヘッダーを実装しよう!」の続きになります。
もちろん前回の記事を見なくても画面遷移はできるのですが、全く同じように作っていきたい方は、「Material UIを使ってヘッダーを実装しよう!」を参考にしてみてください!
- SPAとは
-
SPAは、シングルページアプケーションの略になります。
単一ページのアプリケーションであり、リンクなどをクリックしてもブラウザでページの更新が発生しないのが特徴です。ページロード時に全てのHTML、CSS、JSを取得し、以降はデータの受け渡しで画面を変更する仕組みです。
データが切り替わるとDOM操作でフロント側で画面を書き換えます。SPAは初期ロード時に時間が掛かってしまいますが、以降はデータの受け渡しだけなので高速で動作します。
- react-router-domとは
-
SPAはHTMLが1つであり、従来サーバ側で行っていたHTMLの振り分け作業ができません。
このままでは画面遷移が行えない状態です。SPAで画面遷移相当の実装を助けてくれるのが、react-router-domになります。
正確にはDOM操作で画面遷移のようなことをしてくれるので従来の画面遷移より高速です。
本記事はReact・TypeScript・Redux Toolkitの利用を前提に実装をしていきます。
構築からデプロイまでやっていきますので、必要に応じて他の記事も参考にしてみてください。
学習に使った本はこちら!
Amazon Kindle Unlimited でもReactの本はいっぱいあるぞ!
react-router-domの導入
まずはreact-router-domを導入していきましょう!
react-router-domのインストール
- react-router-domのインストールは、npmで行います。(yarnで行う方は、読み替えてください。)
- react-router-dom:ルーティングを行うライブラリ
- @types/react-router-dom:react-router-domの型定義(javascriptの方は不要)
$ npm install react-router-dom
$ npm install -D @types/react-router-dom
package.jsonを確認
- 念のためですが、ちゃんとインストールできているかpackage.jsonを確認しておきましょう!
- ハイライトが表示されている箇所を確認できれば問題ないです!
{
"name": "piita-client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.11.2",
"@reduxjs/toolkit": "^1.6.1",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"@types/jest": "^24.9.1",
"@types/node": "^12.20.16",
"@types/react": "^16.14.11",
"@types/react-dom": "^16.9.14",
"@types/react-redux": "^7.1.18",
"node-sass": "^6.0.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-redux": "^7.2.4",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"typescript": "^4.1.6"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/react-router-dom": "^5.1.8",
"@typescript-eslint/eslint-plugin": "^4.28.4",
"@typescript-eslint/parser": "^4.28.4",
"eslint": "^7.31.0",
"eslint-config-prettier": "^8.3.0",
"prettier": "^2.3.2"
}
}
導入はいつも通りの手順じゃな。
画面遷移用のPageの作成
続いては、画面遷移の動作確認用のPageを作成しておきます!
必要なファイルを作成しておく
- 今回は、HomePage、Sample1Page、Sample2Pageを作成しますので、必要なファイルを作成しておきます。
- components>pages>homePage配下に、tsxとscssを作成
・HomePage.tsx
・HomePage.module.scss - components>pages>sample1Page配下に、tsxとscssを作成
・Sample1Page.tsx
・Sample1Page.module.scss - components>pages>sample2Page配下に、tsxとscssを作成
・Sample2Page.tsx
・Sample2Page.module.scss - 下の画像のような構成になっていれば大丈夫です!
HomePage.tsxの編集
- 初期表示用の画面を作成するために、HomePage.tsxを編集します。
- 今回のButtonもMaterial UIのSampleをコピペしています。
import React from "react";
import Button from "@material-ui/core/Button";
const HomePage = (): JSX.Element => {
return (
<div>
<Button
variant="contained"
color="primary"
>
SAMPLE1
</Button>
<Button
variant="contained"
color="secondary"
>
SAMPLE2
</Button>
</div>
);
};
export default HomePage;
Sample1Pageの編集
- 遷移後用の画面を作成するために、Sample1Page.tsxを編集します。
- 基本的には、HomePage.tsxと同様です。Backボタンを追加しています。
import React from "react";
import Button from "@material-ui/core/Button";
const Sample1Page = (): JSX.Element => {
return (
<div>
<div>SAMPLE1</div>
<div>
<Button
variant="contained"
color="primary"
>
HOME
</Button>
<Button variant="contained" >
SAMPLE2
</Button>
<Button variant="contained" color="secondary" >
BACK
</Button>
</div>
</div>
);
};
export default Sample1Page;
Sample2Page.tsxの編集
- 遷移後用の画面を作成するために、Sample2Page.tsxを編集します。
- 基本的には、Sample1Page.tsxと同様です。
import React from "react";
import Button from "@material-ui/core/Button";
const Sample2Page = (): JSX.Element => {
return (
<div>
<div>SAMPLE2</div>
<div>
<Button
variant="contained"
color="primary"
>
HOME
</Button>
<Button variant="contained">
SAMPLE1
</Button>
<Button variant="contained" color="secondary">
BACK
</Button>
</div>
</div>
);
};
export default Sample2Page;
react-router-domの実装
続いては、react-router-domの実装を追記していきましょう!
SwitchとRouteを追加する!
- src>Routes.tsxを作成する。
- constでPageのPathを定義しておくと、後々便利だと思います。
- Switch:URLとRouteを上から順番に比較し、最初にマッチしたコンポーネントをレンダリング
- Route:ルーティング先のURLと、そのURLで表示したいコンポーネントを指定
- exact:URLに完全一致した場合にマッチ
import React from "react";
import { Switch, Route, Redirect } from "react-router-dom";
import HomePage from "./components/pages/homePage/HomePage";
import Sample1Page from "./components/pages/sample1Page/Sample1Page";
import Sample2Page from "./components/pages/Sample2Page/Sample2Page";
export const Path = {
home: "/",
sample1: "/sample1",
sample2: "/sample2",
};
const Routes = (): JSX.Element => {
return (
<div>
<Switch>
<Route exact path={Path.home} component={HomePage} />
<Route exact path={Path.sample1} component={Sample1Page} />
<Route exact path={Path.sample2} component={Sample2Page} />
<Redirect to={Path.home} />
</Switch>
</div>
);
};
export default Routes;
Linkを追加する!
- それぞれのPageのボタンに下記を追加していきます。
これは、MaterialUIを使う場合のLinkの追加方法になります。通常の場合は、<Link></Link>で対応することになります。 - componentにreact-router-domのLinkコンポーネントを追加します。
- toに遷移先のURLを追加します。
- historyをpropsで受け取ることにより、{history.goBack}で1つ前の画面に戻ることが可能です!
- Link:遷移先URLを指定
import React from "react";
import Button from "@material-ui/core/Button";
import { Link } from "react-router-dom";
import { Path } from "../../../Routes";
const HomePage = (): JSX.Element => {
return (
<div>
<Button
variant="contained"
color="primary"
component={Link}
to={Path.sample1}
>
SAMPLE1
</Button>
<Button
variant="contained"
color="secondary"
component={Link}
to={Path.sample2}
>
SAMPLE2
</Button>
</div>
);
};
export default HomePage;
import React from "react";
import { RouteComponentProps } from "react-router-dom";
import { Link } from "react-router-dom";
import Button from "@material-ui/core/Button";
import { Path } from "../../../Routes";
type PropsTypes = RouteComponentProps;
const Sample1Page = ({ history }: PropsTypes): JSX.Element => {
return (
<div>
<div>SAMPLE1</div>
<div>
<Button
variant="contained"
color="primary"
component={Link}
to={Path.home}
>
HOME
</Button>
<Button variant="contained" component={Link} to={Path.sample2}>
SAMPLE2
</Button>
<Button variant="contained" color="secondary" onClick={history.goBack}>
BACK
</Button>
</div>
</div>
);
};
export default Sample1Page;
import React from "react";
import { RouteComponentProps } from "react-router-dom";
import { Link } from "react-router-dom";
import Button from "@material-ui/core/Button";
import { Path } from "../../../Routes";
type PropsTypes = RouteComponentProps;
const Sample2Page = ({ history }: PropsTypes): JSX.Element => {
return (
<div>
<div>SAMPLE2</div>
<div>
<Button
variant="contained"
color="primary"
component={Link}
to={Path.home}
>
HOME
</Button>
<Button variant="contained" component={Link} to={Path.sample1}>
SAMPLE1
</Button>
<Button variant="contained" color="secondary" onClick={history.goBack}>
BACK
</Button>
</div>
</div>
);
};
export default Sample2Page;
BrowserRouterを追加する!
- App.tsxにBrowserRouterを追加します。
BrowserRouterは1回しか使えないので、必然的にトップ階層に近い場所に追加することになると思います。 - BrowserRouter:BrowserRouter配下で、react-router-domのコンポーネント(Route,Linkなど)を利用することが可能になります。Routerという似たコンポーネントもありますが、違いはRouterのみではHistoryが使えないということです。(別途コンポーネントを使えば使えるようになりますが、基本はBrowserRouterでいいでしょう。)
import React from "react";
import styles from "./App.module.scss";
import { BrowserRouter } from "react-router-dom";
import Header from "./components/modules/header/Header";
import Routes from "./Routes";
function App(): JSX.Element {
return (
<div className={styles.root}>
<div className={styles.wrapper}>
<BrowserRouter>
<Header />
<div className={styles.page}>
<Routes />
</div>
</BrowserRouter>
</div>
</div>
);
}
export default App;
なんとかできたぞ!
動作確認
最後に動作確認しておきましょう!
- npm startでアプリを起動する
- HomePageが表示されることを確認する
- SAMPLE1ボタンを押下する
- SAMPLE1画面が表示されることを確認する
- SAMPLE2ボタンを押下する
- SAMPLE2画面が表示されることを確認する
- BACKボタンを押下する
- SMAPLE1画面が表示されることを確認する
- BACKボタンを押下する
- HOME画面が表示されることを確認する
Historyも問題なく動作してますね!
まとめ
今回は、Reactアプリケーションにreact-router-domを導入して画面遷移をしてみました。
また、今回のReactを勉強するにあたり利用した教材をあげています。
主に本(Amazon Unlimitedを含む)とUdemyの動画教材を利用しています。ここには私なりに理解した内容をもとに独自に内容を考えて共有しているので興味ある方は、本やUdemyを購入して勉強してみることをおすすめします。
学習に使った本はこちら!
Amazon Kindle Unlimited でもReactの本はいっぱいあるぞ!