React-Routerのprops.childrenってなんだよ

react-routerを使う上でprops.childrenの意味がいまいち理解できていなかったのでアウトプット。

## ルーティングの設定

react-routerを使う上ではルーティングをルートコンポーネントで設定する

```jsx
<Router>
  <Header>
    <Route path="/users/:content" component={UserModal}/>
  </Header>
  <Container>
    <Switch>
      <Route exact path='/'>
        <Index>
        </Index>
      </Route>
      <Route path="/users/mypage">
        <MyPage>
          <Route exact path="/users/mypage">
            <UserInfo></UserInfo>
          </Route>
          <Route path="/users/mypage/recommends">
            <MyRecommendedBooks></MyRecommendedBooks>
          </Route>
          <Route path="/users/mypage/edit">
            <EditUserInfo></EditUserInfo>
          </Route>
        </MyPage>
      </Route>
    </Switch>
    <Route path="/books/new">
      <NewBookModal>
      </NewBookModal>
    </Route>
  </Container>
</Router>
```

Routerタグで囲み、Routerタグの中のRouteタグでルーティングを設定する。
Routeタグの中に書いたコンポーネントがpathプロパティのURLにアクセスした際に読み込まれる。

今回props.childrenを採用したのは以下の箇所

```jsx
<Route path="/users/mypage">
  <MyPage>
    <Route exact path="/users/mypage">
      <UserInfo></UserInfo>
    </Route>
    <Route path="/users/mypage/recommends">
      <MyRecommendedBooks></MyRecommendedBooks>
    </Route>
    <Route path="/users/mypage/edit">
      <EditUserInfo></EditUserInfo>
    </Route>
  </MyPage>
</Route>
```

マイページ内でサイドバーをクリックして表示するコンテンツを切り替える2カラムレイアウトを実装したい。

## Linkの設定

次に設定したルーティングに対応するLinkを設定する。

```jsx
// react-routerの読み込み
import { Link } from "react-router-dom";
```

まずはimportして

```jsx
class MyPage extends React.Component {
  render () {
    return (
      <MyPageWrapper>
        <MyPageHeader>
          テストさんのマイページ
        </MyPageHeader>
        <MyPageBody>
          <MyPageSideBar>
            <ul>
              <li>
                <Link to="/users/mypage/recommends">
                  推薦図書一覧
                </Link>
              </li>
              <li>
                <Link to="/users/mypage/edit">
                  プロフィール編集
                </Link>
              </li>
              <li>
                <Link to="/users/:id/books">
                  ログアウト
                </Link>
              </li>
            </ul>
          </MyPageSideBar>
```

こんな感じでマイページのサイドバーにLinkを入れる。toプロパティが先程のRouteのpathプロパティと対応する。
こうすることで、Routeで設定したpathとLinkのクリック動作が対応し、コンポーネントが読みこまれる。

## コンポーネントの表示箇所を決める

ここでようやくprops.childrenの出番だ。

```jsx
    <li>
      <Link to="/users/:id/books">
        ログアウト
      </Link>
    </li>
  </ul>
  </MyPageSideBar>
    <MyPageMainContent>
      {this.props.children}
    </MyPageMainContent>
  </MyPageBody>
</MyPageWrapper>
```

こんな感じでマイページのメインコンテンツに{this.props.children}という記述を入れるとここにRoute以下のコンポーネントたちが
読み込まれる。

実際に検証ツールでchildrenプロパティをみてみると確かにRouteタグが3つはいっていることがわかる。
これでthis.props.childrenがRouteに応じたコンポーネントの表示をやってくれているということがわかる。
![MyRecommendedBooks.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652172/c636dc2f-ad37-e4a1-67a2-61bc8937f552.png)

この際気をつけるのは初期設定で表示したいコンポーネントにはexactオプションをつけること。

```jsx
<Route exact path="/users/mypage">
  <UserInfo></UserInfo>
</Route>
```

この/users/mypageというパスは他のコンポーネントにも共通しているのでexactをつけないと例えば/users/mypage/recommendsにアクセスしたときにも
読み込まれてしまう。

## 挙動

こんな感じにサイドバーのクリックでメインコンテンツを切り替えることに成功。
![recommended-books-6-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652172/b85a7440-d277-b3f0-6f31-1a2b0776e21f.gif)


### 参考
https://qiita.com/TsutomuNakamura/items/34a7339a05bb5fd697f2#navigate