今回はReact Routerについてアウトプットしていきたいと思います。やっぱりReact難しいですが、何とか食らいついてます…!
React Router 使い方
まずはReact Routerをインストールします。
$ npm install react-router-dom
予め定義しておいた3つのコンポーネントをApp.jsでimportし、React Routerでルーティングさせることにします。
import React from 'react';
import './App.css';
import {
BrowserRouter as Router,
Switch,
Route,
} from "react-router-dom";
// components
import { Restaurants } from './containers/Restaurants.jsx';
import { Foods } from './containers/Foods.jsx';
import { Orders } from './containers/Orders.jsx';
function App() {
return (
<Router>
<Switch>
// 店舗一覧ページ
<Route
exact
path="/restaurants">
<Restaurants />
</Route>
// フード一覧ページ
<Route
exact
path="/foods"
>
<Foods />
</Route>
// 注文ページ
<Route
exact
path="/orders">
<Orders />
</Route>
</Switch>
</Router>
);
}
export default App;
まず、<Router>...</Router>
で全体を囲み、ルーティング先のコンポーネントを<Switch>...</Switch>
で囲みます。そして、各ルートに対応するコンポーネントや各種オプションを定義していくといった使い方をします。
componentの指定ですが、下記どちらでも表示ができます。
// どちらでも可
<Route
exact
path='/orders'>
<Orders />
</Route>
<Route
exact
path='/orders'
component={Restaurants}>
</Route>
switchとは
Switchが何かというと、最初にマッチしたルートのみを表示するというものです。以下は公式の説明文です。
「Renders the first child <Route> or <Redirect> that matches the location.」
exactとは
exactはデフォルトではfalseになっており、ここをtrueにすると(exact={true}またはexact)、pathに指定したパス文字列と、windowオブジェクトのlocation.pathNameが完全一致した場合のみコンポーネントを返すようになります。例えば、/restaurantsにexactを指定しない場合、今後、/restrants/:id/foodsというパスを追加した際も/restaurantsがマッチし表示されてしまうということになります。
propsを渡す方法
フード一覧ページのURLを/restaurants/${restaurantsId}/foods
としたいとします。その場合に<Foods />はrestaurantsIdをpropsとして受け取らなければなりません。
restaurantsIdを受け取る方法として、matchオブジェクトを使います。matchオブジェクトが何なのかを知るためにコンソールで確認して見ます。
paramsの中にrestaurantsIdが入っているのが分かります。これを使って受け取ることができます。
matchオブジェクトのパラメーターとして指定したい場合はパスの先頭にコロン(:)をつけます。
import React, { Fragment } from 'react';
export const Foods = ({match}) => {
return (
<Fragment>
フード一覧
<p>
restaurantsIdは {match.params.restaurantsId} です
</p>
</Fragment>
)
}
ただしこのmatchオブジェクトはコンポーネントの指定をcomponent={Foods}としたときのみしか使えないので注意!
一方、コンポーネントの指定を<Foods />とした場合のpropsの渡し方はこのようになります。
<Route
exact
path="/restaurants/:restaurantsId/foods"
render={({ match }) =>
<Foods match={match} />
}
/>
component={Foods}とするのと比べて、記述量が多くなるので個人的には前者が好みかなと思いました。一方、こちらの書き方ではmatchでなく好きな名前のpropsにして渡せるのでFoods.jsxを完結に書きたい場合はこのような書き方もありなのかなと感じました。
さいごに
新しい言語を習得するときには、覚えることがたくさんあってほんとに大変です。焦らずコツコツやっていきたいと思いました。
ここまで読んでいただきありがとうございました。