[簡単]React x LaravelのSPAで作るチュートリアル②(ルーティング編)

# SPAで作るタスク管理アプリのチュートリアル - ルーティング編

今回は第②弾でReact側ルーティングを設定する部分をやっていくで
>
①[環境構築(Docker/Laravel/React.js/Material-UI)](https://qiita.com/morry_48/items/abd620f051fb4f36dcc2)
②React側でルーティング設定
③[Reactで一覧テーブル作成](https://qiita.com/morry_48/items/d0ee66eda70020c3f266)
④[seederで作ったDBのデータをReactに渡して一覧に表示](https://qiita.com/morry_48/items/b9287bbd4a7d4d312c65)
⑤[新規登録機能](https://qiita.com/morry_48/items/5b2d80b620b3623a4e33)
⑥[編集・削除機能](https://qiita.com/morry_48/items/261becf645a76eec13cf)


## react-router-domとは
`react-router-dom`ってなんやねんって話なんやけど、簡単に言うとURLのPathに対してReact側で表示するコンポーネントを切り替えることができるで。
使い方とか詳しいことに関しては、まぁググってや。

### こんなんできるようになるで

[![Image from Gyazo](https://i.gyazo.com/b142cfef75680599f3bb9828170fa8cf.gif)](https://gyazo.com/b142cfef75680599f3bb9828170fa8cf)
ボタンクリックするとページ切り替えできるような機能をこれから作っていくな。

## npmでreact-router-domを導入

### docker-compose exec web npm install react-router-domを実行
```php
$  docker-compose exec web npm install react-router-dom
docker-compose exec web npm install
---------下記のようなメッセージ出たらOK
added 10 packages, and audited 1379 packages in 7s

102 packages are looking for funding
  run `npm fund` for details

42 vulnerabilities (35 moderate, 7 high)

```

こんな感じでpackage-jsonが更新されるはずやわ

```package.json
    "dependencies": {
        "@material-ui/core": "^4.11.4",
        "react-router-dom": "^5.2.0"
    }
```

## ルーティング設定のため/resources/js以下のディレクトリ構成を変更する
やることは
- /components下のExample.jsを新規ディレクトリpages下に移動
- /js直下に新規ファイルroute.jsを作成

実行後のディレクトリ構成はこんな感じ
## VSCODE使っててExapme.jsの移動のときに、「import先のディレクトリを変えますか」的なメッセージが出たら「はい」を押す

```
┗ js
  ┗ components       (Example.jsを空になる)
  ┗ pages            (新規ディレクトリ)
    ┗ Example.js     (/componentsから移動)
  ┗ app.js
  ┗ bootstrap.js
  ┗ route.js         (新規作成ファイルで中身はまだ空のままでOK)
```

### /js直下のapp.jsがエディタが良しなにやってくれていることを確認する
(変更されていない場合は自分で変更を加える)

```app.js
// 15行目
- require('./components/Example');
+ require('./pages/Example');
```


### pages下のExample.jsが表示できることを確認

```Example.js
  <div className="card-header">React導入できたわな？？</div>
　 //13行目辺り
-  <div className="card-body">Im an example component!</div>
+  <div className="card-body">pages下に移動出来た？？</div>
  <Button color="secondary" variant="contained">ワイがMaterial-UIのボタンやな？？</Button>

```

### ビルドする
```php
$ make npm-dev

```

localhostにアクセスし表示できることを確認
![スクリーンショット 2021-05-01 10.32.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/b4f5cafe-73d5-63ff-62c0-7da12b636292.png)

「pages下に移動出来た？？」が表示できていればOK


### 変更差分は下記のようになるはずや
![スクリーンショット 2021-05-01 10.32.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/d127de41-07f5-5024-31d6-7907c6471153.png)

### コミットしておこう
```php
$ git add .
$ git commit -m "react-router-dom導入しディレクトリ変更"
```
## react-router-domを利用してページを表示してみる
laravelで`php artisan ui react --auth`によってReactを導入した場合、
`/js/app.js`が読み込まれる様になっているな。

先程requireの部分を
`'./components/Example'` →　`'./pages/Example'`に変えたことによって
pages下のExample.jsが表示されたことからも分かるように、
app.jsの中のrequire()の中で呼ばれたjsファイルが一番最初に呼ばれるんやな。

React側でルーティングしたいので最初に呼ばれるファイルを
`/js/route.js/`


### /js/app.jsを変更する

```app.js
// 15行目
- require('./pages/Example');
+ require('./route');
```


### route.jsに下記を貼り付ける
```jsx
import React from 'react';
import ReactDOM from 'react-dom';
import {
    BrowserRouter,
    Route,
    Switch,
  } from 'react-router-dom';
import Example from './pages/Example';

  function App() {
    return (
        <div>
            <Switch>
             //ここに、pathと対応するコンポーネントを書いていく
            </Switch>
        </div>
    );
}

  ReactDOM.render((
    <BrowserRouter>
      <App />
    </BrowserRouter>
  ), document.getElementById('app'))

```

使っているタグがどんな意味か知りたかったらreact-router-domをimportしてるから、ドキュメント読もうな。
[公式ドキュメント](https://reactrouter.com/)

### <Switch>の中にルーティングの設定を書いていくで

```jsx
//route.jsに下記を追記
            <Switch>
                <Route path='/example' exact component={Example} />
            </Switch>

```

これはpathが/exampleだったらExampleコンポーネントを表示するっているルーティングの設定やね。

### 変更箇所がわかるようにボタンの文字を変更し不要な記述を削除する

```Example.js

                        <div className="card-header">React導入できたわな？？</div>

                        <div className="card-body">pages下に移動出来た？？</div>
//14行目のボタンを「Homeに遷移ボタン」に変更する
-                        <Button color="secondary" variant="contained">ワイがMaterial-UIのボタンやな？？</Button>
+                        <Button color="secondary" variant="contained">Homeに遷移ボタン</Button>
                    </div>
                </div>
            </div>


export default Example;

下記の表示設定はroute.js側で行えるようになったため、削除
//if (document.getElementById('app')) {
//    ReactDOM.render(<Example />, document.getElementById('app'));
//}

```

### ビルドする
```php
$ make npm-dev
```
先程同様にlocalhostにアクセスしたら、返す対象がないため、jsエラーが出るはず。

localhost/exampleにアクセスすると下記が表示されるはず

![スクリーンショット 2021-05-01 18.52.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/fdebfa29-7f46-99fd-7d3c-d5c6282ad433.png)

ボタンが変わっていればOKな！！！！


### コミットしとくで
```php
$ git add .
$ git commit -m "routerを経由してページを表示"
```

## もう一つページ(Home.js)を用意してボタンで遷移できるようにしてみる
/pagesディレクトリにはExacple.jsとHome.jsが存在する状況になるで
ファイル作れたら進んでな。

### /pages/Home.jsを用意し下記の様に設定する


```Home.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Button, Card } from '@material-ui/core';

function Home() {
    return (
        <div className="container">
            <Card>
                <Button color="primary" variant="contained"　href={`/example`}>Exampleに遷移</Button>
            </Card>
        </div>
    );
}

export default Home;

```

ボタンが一つあるだけの画面のコンポーネントやな。

表示するにはルーティングの設定がいるな。

### Home.jsのルーティングを記載する

```route.js
// 8行目 以降
import Example from './pages/Example'; 
// Exampleの下にHome.jsをインポートする
import Home from './pages/Home';

  function App() {
    return (
        <div>
            <Switch>
                <Route path='/example' exact component={Example} />
                // Homeコンポーネントを表示するための設定を記述
                <Route path='/' exact component={Home} />
            </Switch>
        </div>
    );
}

```

コンポーネントのimportとルーティングの設定を書いただけやな。
`exact`ってなんやねんって気になってる人いてるかもしれへんけど、
これ書いてなかったら前方一致で判定されるはずやから基本は書いといたほうがえと思うわ。


### ビルドする

```php
$ make npm-dev

```

ビルドできたらlocalhostにアクセスして下記のように表示されたらOKや


![スクリーンショット 2021-05-01 20.36.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/17d52ec9-d679-e94d-c0ad-25ad709648bd.png)

表示されているボタンにhrefに`/example`を設定したのでクリックすると
expampleページに遷移できるはずやで

## Exampleコンポーネントのボタンにもhrefを設定する

```Example.js
//14行目にhrefを追加
                 <Button color="secondary" variant="contained" href={`/`}>Homeに遷移ボタン</Button>

```

これで互いのページを行き来できるようになったはずやで

### ビルド
```php
$ make npm-dev

```

### ビルドできたら互いのページ行き来してみて遊んでみたや

つかめてきたら新しいページを用意してroute.jsにルーティングの設定を記述したら
理解深まると思うわ

### コミットしとこうな
```php
$ git add .
$ git commit -m "Homeコンポーネントを作成しrouteingの設定"

```


### 纏め

このようにlaravel側では[環境構築編](https://qiita.com/morry_48/items/abd620f051fb4f36dcc2)で設定したように、どのパスが指定されたとしても`app.blade.php`を表示するように設定しておいてReact.js側でルーティングの設定をすることが出来たな。

ここまで出来たらReactやったことある人ならどんどんページ作っていくことはできそうやな。
ただ`データのやり取りが出来てないからそれは次回以降`の記事に書いていくことにするで

次はReactで一覧テーブルのコンポーネント作っていくところをやっていこうと思うで。
## 次回はReactで一覧表示
![スクリーンショット 2021-04-29 19.30.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/ac3856d1-6216-a653-80d6-f07fd22246d2.png)

ほなここまで出来た人はLGTMしといてな。

ソースはGitHubに乗せておくから分からんときはコミット履歴見たら解決できるかもな。
https://github.com/morry48/LaravelReactTaskApp