17
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

react-routerに入門する

Last updated at Posted at 2019-07-08

数か月前にreact-routerとReduxを同時に学ぼうとして挫折したので、今回はまず順を追ってreact-routerを学習する。

インストールするもの

vueのときと同じかな? と最初に何も考えずにreact-routerを入れたのですが、調べるとどうやらこれはコアの部分。
ウェブアプリケーションを構築する為に必要なのは「react-router-dom」の方でした(こちらを入れるとreact-routerも一緒に入ってくれます)。

今回は
react-router-dom 5.0.1
を使用しています。

まずはApp.jsにざらっと書いてみる

index.js
import React from 'react'
import ReactDOM from 'react-dom'
import './styles.scss'
import App from './App'

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
App.js
import React, { Component } from 'react'
import { BrowserRouter, Route, Link } from 'react-router-dom'

const App = () => (
  <BrowserRouter>
    <h1>react-routerに入門する。</h1>
    <nav>
      <ul>
        <li><Link to='/'>Index</Link></li>
        <li><Link to='/second'>Second</Link></li>
        <li><Link to='/third'>Third</Link></li>
      </ul>
    </nav>
    <article>
      <Route exact path='/' component={Index} />
      <Route path='/second' component={Second} />
      <Route path='/third' component={Third} />
    </article>
  </BrowserRouter>
)

const Index = () => (
  <div>
    <h2>Index</h2>
    <p>インデックスページ</p>
  </div>
)
const Second = () => (
  <div>
    <h2>Second</h2>
    <p>二番目のページです</p>
  </div>
)
const Third = () => (
  <div>
    <h2>Third</h2>
    <p>三番目のページです</p>
  </div>
)

export default App

router1.gif

リンクは<Link to='/'>で書き、<Route />でルーティングを設定すれば良いので、ここまではVueのときと然程遠くない感覚で書けました。
(色々な方の記事を見ていると、BrowserRouterにasで「Router」と付けている人が多いみたいだったんですが何故だろう……)

ページごとにファイルを分けたい

といってもこれは単に分けるだけ。

pages/Index.js
import React, { Component } from 'react'

const Index = () => (
  <div>
    <h2>Index</h2>
    <p>二番目のページです</p>
  </div>
)

export default Index

他ページも同様に。

App.js
import React, { Component } from 'react'
import { BrowserRouter, Route, Link } from 'react-router-dom'
import Index from './pages/Index'
import Second from './pages/Second'
import Third from './pages/Third'

const App = () => (
  <BrowserRouter>
    <h1>react-routerに入門する。</h1>
    <nav>
      <ul>
        <li><Link to='/'>Index</Link></li>
        <li><Link to='/second'>Second</Link></li>
        <li><Link to='/third'>Third</Link></li>
      </ul>
    </nav>
    <article>
      <Route exact path='/' component={Index} />
      <Route path='/second' component={Second} />
      <Route path='/third' component={Third} />
    </article>
  </BrowserRouter>
)

export default App

動的ルートマッチングしたい

したい。
今回はSecondの下層ページとして実装します。
まずは中身から。

pages/SecondChild.js
import React, { Component } from 'react'

const SecondChild = (props) => {
  const { id } = props.match.params

  return (
    <div>
      <h2>SecondChild</h2>
      <p>{id}のページです</p>
    </div>
  )
}

export default SecondChild

次いでApp.jsを書いていくんですが……。
以下、失敗例です(´・ω・`)。

App.js
import React, { Component } from 'react'
import { BrowserRouter, Route, Link } from 'react-router-dom'
import Index from './pages/Index'
import Second from './pages/Second'
import SecondChild from './pages/SecondChild'
import Third from './pages/Third'

const App = () => (
  <BrowserRouter>
    <h1>react-routerに入門する。</h1>
    <nav>
      <ul>
        <li><Link to='/'>Index</Link></li>
        <li><Link to='/second'>Second</Link></li>
        <li><Link to='/second/neko'>Second-neko</Link></li>
        <li><Link to='/third'>Third</Link></li>
      </ul>
    </nav>
    <article>
      <Route exact path='/' component={Index} />
      <Route path='/second' component={Second} />
      <Route path='/second/:id' component={SecondChild} />
      <Route path='/third' component={Third} />
    </article>
  </BrowserRouter>
)

export default App

image.png

あれっ、ふたつ出ちゃった。
SecondとSecondChildを逆に書くべきだった?と調べてみるもそういうことではなく。
単純にexactの記載が抜けていたのでした。

    <article>
      <Route exact path='/' component={Index} />
      <Route exact path='/second' component={Second} />
      <Route path='/second/:id' component={SecondChild} />
      <Route path='/third' component={Third} />
    </article>

Routeは前方一致するものがあれば全てのコンポーネントが表示されるため、一致させたくないものにはexactが必要です。
これで完全一致の場合のみ表示されるようになります。

余談

今回記事を書くにあたって、vue-routerで言うところの:to={name: 'hoge'}的な書き方をしたいと思ったのですが、どうにも書き方を見付けられませんでした。
単に見付けられていないのか、そもそもreactでは必要にならないのか……。
触っていくうちに分かると思うので、今後の課題とします。

参考記事

react-router@v4を使ってみよう:シンプルなtutorial
https://qiita.com/muiscript/items/b4ca1773580317e7112e

React Roter v4 (RRv4) を使用した時の備忘録
https://blog.kazu69.net/2017/08/10/using-react-router-v4/

17
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?