React

【React】React Routerの使い方(基礎)

今回は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を完結に書きたい場合はこのような書き方もありなのかなと感じました。

さいごに

新しい言語を習得するときには、覚えることがたくさんあってほんとに大変です。焦らずコツコツやっていきたいと思いました。
ここまで読んでいただきありがとうございました。

ABOUT ME
sakai
東京在住の30歳。元々は車部品メーカーで働いていてましたが、プログラミングに興味を持ちスクールに通ってエンジニアになりました。 そこからベンチャー → メガベンチャー → 個人事業主になりました。 最近は生成 AI 関連の業務を中心にやっています。 ヒカルチャンネル(Youtube)とワンピースが大好きです!