React Basic

# 概要

Reactの作り方をセミナーした時の資料
Reactを使ったことのない人に、function componentとreact hooksを
最初から使う形で説明

# React

facebookが開発した主にブラウザで動作するfrontendの開発framework

対抗馬に `Vue.js` がある。
使い勝手はどっちもどっちくらいだったが、 2017年頃から
Reactの拡張である `React Hooks` が実装されたことによって
一気にReactが使いやすくなった印象。

# 事前準備

## JavaScriptの基本

Reactを学ぶ前にJavaScriptの基本を身につけておく必要がある。

[JavaScriptBasicへのリンク](https://qiita.com/AkihiroTakamura/items/3149111aa2aca10ffd91)

以降の内容は基本コーディングを踏まえた記述になる


## 環境構築

Reactを動かす為の環境を用意しておく。


### `node` のインストール

`Node.js` は JavaScriptベースで作成したプログラムを
ブラウザでなくアプリケーションとして動かすための実行環境。

エンジンとしての `Node.js` だけでなく、
パッケージマネージャとしての `npm` が同梱されていて
各パッケージのインストール・利用が簡単にできる

既にインストールされているかもしれないので、コマンドラインより以下で確認する

`node --version`

`v12.16.3` のように表示されたら既にインストールされている。
nodeのバージョン差の影響を受けないように、既にインストールされている場合は
バージョンをメモしておいて、nodeを一旦アンインストールしておく。


nodeをインストールする場合、そのままインストールするのではなく、
node自体のバージョンを切り替えられるツールを経由してインストールする。

Macなら `nodebrew` 、 windowsなら `Nodist` を利用


#### Nodistのインストール

[github](https://github.com/nullivex/nodist/releases)にインストーラーが用意されているので
ダウンロードしてインストールする。

インストールできたら利用するnodeをバージョン指定でインストールする
今回説明は `12.16.3` を使う。

`nodist + 12.16.3`

nodeが自動的にインストールされるので、以下でそのバージョンを利用するようにする

`nodist 12.16.3`

これでnodeを確認するとバージョン指定したnodeになっているはず

`node --version`

> プロジェクトにより使用しているNodeのバージョンが違う場合があるので
> 上記の方法でバージョンを切り替えて対応する


## テキストエディタの準備

`atom` を使う。

githubが開発してるテキストエディタ。
`visual sutudio code` に押されがち。

[公式](https://atom.io/) からインストールする。

インストールできたら、atomで利用するパッケージをインストールする。
とりあえず必要そうなものを用意しておいた。
以下の内容を `packages.txt` というファイルに書く。

```
atom-beautify
autocomplete-paths
color-picker
convert-to-utf8
document-outline
file-icons
git-history
git-log
git-plus
language-javascript-jsx
linter
linter-eslint
linter-flake8
linter-jsonlint
linter-ui-default
merge-conflicts
minimap
minimap-find-and-replace
```

そして以下のコマンドでatomに一括インストールする

`apm install --packages-file packages.txt`


# Reactでアプリを作る

## プロジェクトの作成

Reactを始めるにあたり、本来は初期設定が諸々必要なのだが
そのへんを簡単にしてくれてる `Create React App` というパッケージがあるので使う。

まず、コマンドラインよりローカルの任意の場所に移動して以下を実行する

```
npm i -g npx
npx create-react-app react-training
```

> `npx` というコマンドは `node` をインストールするとついてくる（古いバージョンのnodeにはない）
> `npx` は `npm install -g` でグローバルパッケージをインストールしてから実行するコマンドについて
> ローカルにインストールすることなく実行することができる便利なコマンド。
> これを使うことで、グローバルパッケージのバージョンが古いとかの問題を回避することができる。

実行すると `react-training` というフォルダが作成され、中に初期セットが入っている
なにはともあれ、以下を実行する

```
cd react-training
npm start
```

実行すると、ブラウザが立ち上がりトップページが表示される

これでプロジェクト作成はOK


## 最初のReactコーディング

### atomでソースコードを開く

atomを開き、 `react-training` のフォルダをドラッグ＆ドロップする

いろいろファイルが入っている

- publicフォルダ：今の所無視しておいてよい
- srcフォルダ：ここにソースコードを配置する
  - `index.js` ：すべての起点となるソースだが、今の所無視しておいてよい
  - `App.js` ： `index.js` から呼ばれている。まずはここを触っていく
- その他のファイル：とりあえず無視

### `App.js` をいじってみる

`src/App.js` を開く。

なんやら `html` タグのようなものが書かれている。
このタグのところを適当にいじって保存してみる。

> このタグの部分を `jsx` と呼ぶ。
> HTMLタグも書けるし、後から出てくるコンポーネントをタグとしても書くことができる。
> また、タグを動的に変えることがも可能。

と、すぐさまブラウザに反映されていることがわかる

ここで色々楽しんでくれても構わない。


### Function Component

`Create React App` で作成されたソースコードはいくつか気に入らない点がある

- `Function` を使っている
- セミコロンがある

動作は同じだが、書き方を統一したいので書き直しをする。

```javascript

import React from 'react'
import logo from './logo.svg'
import './App.css'

const App = props => { // ここを変えてる
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />

        <h1>Hello React!!!</h1>
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  )
}

export default App
```

セミコロンを全般的に取ったのと、 `App` の定義を `Function` を使わなくしている。
これが基本形として進めていく。


### `App.js` のざっくりした説明

ざっくり説明しておく。現時点ではふーん、そうなんだくらいの把握でOK
細かいことを気にしないでどんどん進んでいくスタイルの方が覚えやすい。
→あとからだんだんわかってくるので。


`import React from 'react'`

`import xx from xx` と書くと、他のJavaScriptモジュールを使うという意味になる。
この場合、 `react` というパッケージから `React` を取り出して使うという意味。
`React` のimportはだいたい必要になるのでとにかく書いておく。

`import logo from './logo.svg'`

`import` はJavaScriptモジュールだけでなく、画像も取り込むことができる。
上記だと、 `logo.svg` という画像ファイルを `logo` という名前で取り込んでいる。

`import './App.css'`

`import` では `css` ファイルも取り込むことができる。
このとおり取り込んでおけば、そのcssが適用された状態になる。簡単。

```javascript
const App = props => {
  return (
    <p>Hello World</p>
  )
}
```

Reactではまずコンポーネントというものをガンガン作っていくことになる。
そしてそのコンポーネントの基本形が上記の形式。

見てのとおり、コンポーネントは関数になっている。また引数に `props` というものを受ける。
そして `return` でタグを返している。


`<div className="App">`

`className` というattributeがついている。これはcss classを指定している。
通常のHTMLでcssクラスを指定する場合、 `class="App"` のように書くが、
Reactの場合は `class=` でなく `className=` で書く必要がある。これはルール。

概ね通常のhtmlで指定できるattributeはそのままReactでも使えるが、
上記のように一部HTMLとは異なる記述になる部分もある。

> `class` がJavaScript上予約語だから・・・

`export default App`

`export` は `import` できる形でモジュールを公開するよ、というコマンド。
上記だと `App` のコンポーネントを公開するという意味になる。

`default` は `import` する時に名前を指定しない場合は `App` 入れるよ。という意味。
とりあえず深く考えなくてもOK


`<img src={logo} className="App-logo" alt="logo" />`

`src={logo}` の部分。このブラケットで囲った中は変数展開の意味になる。
`logo` は上部で importしてきた画像が入っているので、その画像を `img` タグの `src` に入れている。


## 独自のコンポーネントを作ってみる

`App` とは別のコンポーネントを作ってみる。
とりあえず、 `Hello, World` という文字を表示するだけのコンポーネントを作り、
`App` に組み込んでみる。

`App.js` を開き、ソースコードの一番下に `Hello` というコンポーネントを定義する。
そして `<p>` タグでHello Worldを返すようにする


```javascript

const Hello = props => {

  return (
    <p>Hello World</p>
  )
}

```

これで独自のコンポーネントは作成OK。
でもまだ画面には反映されない。組み込んでないから。

ということで `App` のコンポーネント内を変更して、 `Hello` コンポーネントを差し込む。

こんな感じにする

```javascript
return (
  <div className="App">
    <header className="App-header">
      <img src={logo} className="App-logo" alt="logo" />

      <Hello />
      <p>
        Edit <code>src/App.js</code> and save to reload.
      </p>
      <a
        className="App-link"
        href="https://reactjs.org"
        target="_blank"
        rel="noopener noreferrer"
      >
        Learn React
      </a>
    </header>
  </div>
)
```

このように、 `jsx` の中で他のコンポーネントを差し込む場合、
タグにそのコンポーネントの名前を指定するだけでOK


### propsを渡してみる

Componentを定義する時、 `props` という引数を受けていた。
これはComponentへのパラメータを指していて、
必要な情報をComponentに渡すことができる。

とりあえず `Hello` コンポーネントにいくつか `props` を渡すようにする

まず、 `App` の方で、`Hello` を呼ぶ部分に attributeのようにpropsをセットする

```javascript

<Hello name='hoge' suffix='様' />

```

`Hello` の方でpropsを受取り、文字に含めてみる

```javascript

const Hello = props => {

  const {
    name,
    suffix,
  } = props // propsにはobject型でセットされるので、Spread Separatorで取り出せる

  return (
    <>
      <p>Hello World</p>
      <p>{`${name}${suffix}`}</p>  {/* ここを追加  */}
    </>
  )
}

```

`<></>` というタグはReact.Fragmentというコンポーネントでダミーのコンポーネントになる。
JSXの部分は、一番上の要素は１つだけという制限がある。そのため、 `<p>` タグを並べて書くことができない。
そういう時にFragmentを使って、ダミータグを利用してJSXを記述する。

### イベントをつけてみる

要素をクリックした時のアクションをつけてみる。

今度は `Button` というコンポーネントを作成する

```javascript

const Button = props => {
  return (
    <span
      style={{
        backgroundColor: 'lightblue',
        color: 'black',
        outline: 'none',
        fontSize: 18,
        padding: '12px 5px',
      }}
    >ボタンです</span>
  )

}

```

そして `Hello` コンポーネントに `Button` コンポーネントを追加する


```javascript

const Hello = props => {

  const {
    name,
    suffix,
  } = props

  return (
    <>
      <p>Hello World</p>
      <p>{`${name}${suffix}`}</p>
      <Button />  {/* ここを追加  */}
    </>
  )
}

```

これでボタンの表示はできたが、まだクリックした時のイベントを貼っていないので
押しても何も動作しない。

クリックイベントは onClick という propsに関数を渡すことで貼ることができる

```javascript
const Button = props => {

  return (
    <span
      style={{
        backgroundColor: 'lightblue',
        color: 'black',
        outline: 'none',
        fontSize: 18,
        padding: '12px 5px',
      }}
      onClick={() => alert('clicked!')} {/* ここを追加 */}
    >ボタンです</span>
  )

}

```




### stateを使ってみる

Reactでは動的なページにおいて、操作した状態を記録する領域として `state` というものを使うことができる。

例えば、ボタンを１回押すと、１カウントアップするコンポーネントを考えてみる。

さっき作ったButtonコンポーネントで、ボタンを押したらstateを加算するようにしてみる。
stateは `useState` という関数を使って作ることができる
`useState` は `react` が提供しているので `react` からimportして使う

`import React, { useState } from 'react'`

```javascript

const Button = props => {

  const [count, setCount] = useState(0)

  return (
    <span
      style={{
        backgroundColor: 'lightblue',
        color: 'black',
        outline: 'none',
        fontSize: 18,
        padding: '12px 5px',
      }}
      onClick={() => setCount(state => ++state)}
    >{`ボタンです。${count}回押しました`}</span>
  )

}

```

`const [count, setCount] = useState(0)`

`useState` は 引数に初期値を設定できる。今回は 0 を初期値にしている。
`useState` は 戻り値に配列を返し、第１要素に現在の値、第２要素の値を更新する為のメソッドを返す。

なので `count` を見ると現在値がわかり、 `count` を変更するには `setCount` に引数を渡して実行する。

`onClick={() => setCount(state => ++state)}`

`setCount()` でstate countを更新している。
ただ上記の例では、setCount の引数に値でなく、関数を渡している。

setCount に関数を渡すと、その関数の引数に現在のstateを渡してくれるようになっている。
なので、 `setCount(state => ++state)` で、現在のcountが `state` に入り、 その `state` を+1したものを
returnして countを更新するという意味になっている。


> `setCount(++count)` 同じ意味になるが、stateが増えた場合、違うstateを入れてしまう間違いが
> 起こることも考えられるので、関数型をおすすめ


### stateをコンポーネント間で受け渡す

`Button` コンポーネントの中で `state` を利用することができた。

stateにはボタンを押した回数が入っている。
これを `Hello` コンポーネントの方で押した回数毎に `Hello World` の方に回数を表示するようにしたい

そのためには `Hello` コンポーネントで `count` というstateを把握する必要があるが
`count` は `Button` コンポーネントで定義している為、 `Hello` からは見えない。

Componentの階層としては今、こうなっている

```
App
↓
Hello countを知りたいが見えない
↓
Button ここにcount がある
```

この場合、以下のような構成に変更する

```
App
↓
Hello countを定義。setCount関数をpropsでButtonにわたす
↓
Button HelloからもらったsetCountをクリックイベントで更新する
```

こうすることで、 `Hello` は countの値を把握することができ、
`Button` は countの値を更新することができる。


やってみる

```javascript

const Hello = props => {

  const {
    name,
    suffix,
  } = props

  const [count, setCount] = useState(0)

  return (
    <>
      <p>Hello World</p>
      <p>{`${name}${suffix}`}</p>
      <p>{`${count}回押しました`}</p>
      <Button
        setCount={setCount}
      />
    </>
  )
}

const Button = props => {

  const {
    setCount
  } = props

  return (
    <span
      style={{
        backgroundColor: 'lightblue',
        color: 'black',
        outline: 'none',
        fontSize: 18,
        padding: '12px 5px',
      }}
      onClick={() => setCount(state => ++state)}
    >{`ボタンです。`}</span>
  )

}

```

### 副作用を使ってみる

ここまでで、ボタンを押した時にカウント表記を表示するようにできた。
今度はカウントが奇数の場合と偶数の場合とで文字色を変えるようにしてみる。

この場合、 `count` が変わるたびに判定して実行してもいいが
練習のため値を監視して、値が変わったら実行するという副作用を `useEffect` を使って実装してみる

まず、 `useEffect` というものが必要なので react からインポートする

`import React, { useState, useEffect } from 'react'`

そしてuseEffectを使った副作用を実装する

```javascript

const Hello = props => {

  const {
    name,
    suffix,
  } = props

  const [count, setCount] = useState(0)
  const [color, setColor] = useState('white')

  useEffect(() => {
    setColor(
      (count % 2 !== 0)
        ? 'red'
        : 'white'
    )
  }, [count])

  return (
    <>
      <p>Hello World</p>
      <p>{`${name}${suffix}`}</p>
      <p style={{ color }}>{`${count}回押しました`}</p>
      <Button
        setCount={setCount}
      />
    </>
  )
}

```

`const [color, setColor] = useState('white')`

まず、文字色設定の為のstateを追加。初期値は `white`


```javascript
useEffect(() => {
  setColor(
    (count % 2 !== 0)
      ? 'red'
      : 'white'
  )
}, [count])
```

副作用部分。 useEffect は第１引数に関数を。第２引数に配列を受けるようになっている。
第２引数の配列には、変数を詰めることができ、ここに詰めた変数の値が変わった時（とマウントした時）に
第１引数の関数を実行するようになっている。

なので、上記では `count` が変わったら動き出し、
colorに、countが奇数なら `red` を、そうでないなら `white` をセットするようになっている


ただ、この例の場合、わざわざ `useEffect` を使わないでもJSXの中でも実装できる。

```javascript

return (
  <>
    <p>Hello World</p>
    <p>{`${name}${suffix}`}</p>
    <p
      style={{ color: (count % 2 !== 0) ? 'red' : 'white' }}
    >{`${count}回押しました`}</p>
    <Button
      setCount={setCount}
    />
  </>
)

```

このように単純な場合は極力 `useEffect` を使わない方がシンプルになるのでおすすめ。
ただ、複数の値を監視し、どれか一つでも変わったら処理をする場合（変わってない時は処理したくない）等は
変更を検知するロジックを組むのが大変なので、 `useEffect` の利用を検討する


### メモ関数を使ってみる

今度は複数のボタンのそれぞれの押した回数を合計した数字を表示することを考えてみる。

まず、ボタンを２つにして、それぞれのボタンのカウントを記録するstateも２つにする

```javascript
const Hello = props => {

  const {
    name,
    suffix,
  } = props

  const [count, setCount] = useState(0)
  const [count2, setCount2] = useState(0)
  const [color, setColor] = useState('white')

  useEffect(() => {
    setColor(
      (count % 2 !== 0)
        ? 'red'
        : 'white'
    )
  }, [count])

  return (
    <>
      <p>Hello World</p>
      <p>{`${name}${suffix}`}</p>
      <p style={{ color }}>{`${count}回押しました`}</p>
      <Button
        setCount={setCount}
      />
      <p>{`${count2}回押しました`}</p>
      <Button
        setCount={setCount2}
      />
    </>
  )
}

```

２つのカウントを合計した値を表示する。
ただJSXで足し算してもいいが、今回は `useMemo` というものを使ってメモ化した値を使ってみる。

またreactから useMemoをインポートする

`import React, { useState, useEffect, useMemo } from 'react'``

useMemoを使って２つのカウントを監視し、値が変わった場合に合計値を算出するようにする

```javascript
const Hello = props => {

  const {
    name,
    suffix,
  } = props

  const [count, setCount] = useState(0)
  const [count2, setCount2] = useState(0)
  const [color, setColor] = useState('white')

  useEffect(() => {
    setColor(
      (count % 2 !== 0)
        ? 'red'
        : 'white'
    )
  }, [count])

  const summary = useMemo(() => count + count2
  , [
    count,
    count2,
  ])

  return (
    <>
      <p>Hello World</p>
      <p>{`${name}${suffix}`}</p>
      <p style={{ color }}>{`${count}回押しました`}</p>
      <Button
        setCount={setCount}
      />
      <p>{`${count2}回押しました`}</p>
      <Button
        setCount={setCount2}
      />
      <p>{`合わせて${summary}回押しました`}</p>
    </>
  )
}

```

```
const summary = useMemo(() => count + count2
, [
  count,
  count2,
])
```

useMemoはuseEffectと同じように第１引数に値が変わった時の関数、
第２引数に監視する値の配列を受ける。
useMemoはuseEffectと違って戻り値を持っていて、この戻り値には第１引数が返した値が入っている。

上記の summaryをJSXで表示すれば合計値を表示することができる。

useEffectの時のように、useMemoを使わずにJSXでも実装することができる。

```javascript
<p>{`合わせて${count + count2 }回押しました`}</p>
```

ただ、この場合は `useMemo` を使った方が描画負荷が少なくなる為おすすめ。

JSXはpropsやstateがちょっとでも変わった時に全実行され直す。（細かくいくとその中で変更影響ある部分に限られるが）

なので上記のように書くと、count, count2とは別の値が更新された場合でも、 `count + count2` の処理が
実行されることになる。

細かいことだが、こういうものが積み重なっていくとどんどん重いサイトになってしまう。
useMemoは前述のとおり、監視した値が変わった時だけ、処理が実行される為
count1, count2が変更されない限り `count + count2` は実行されない。
という処理上のメリットがある。

## コンポーネントを分割する

`App.js` に `App` やら `Hello` やら `Button` やらの定義をしてきた。

１ファイルにたくさん書くのは限界があるので別のJSファイルにコンポーネントを分ける。

これも `import` と `export` 機構を使えば簡単にできる。

今は `src` 直下の `App.js` を操作しているので、 `src/component` というフォルダを作って
その中に `Hello.js` と `Button.js` を作り、 `App.js` から呼び出すようにしよう。

`src/component/Button.js` を作り、以下のようにする

```javascript
import React from 'react'

export const Button = props => {  // exportをつけることで外部公開になる

  const {
    setCount
  } = props

  return (
    <span
      style={{
        backgroundColor: 'lightblue',
        color: 'black',
        outline: 'none',
        fontSize: 18,
        padding: '12px 5px',
      }}
      onClick={() => setCount(state => ++state)}
    >{`ボタンです。`}</span>
  )

}

```

次に `src/component/Hello.js` を作り、以下のようにする

```javascript
import React, { useState, useEffect, useMemo } from 'react'
import { Button } from './Button' // Buttonコンポーネントを使うのでインポート

export const Hello = props => {

  const {
    name,
    suffix,
  } = props

  const [count, setCount] = useState(0)
  const [count2, setCount2] = useState(0)
  const [color, setColor] = useState('white')

  useEffect(() => {
    setColor(
      (count % 2 !== 0)
        ? 'red'
        : 'white'
    )
  }, [count])

  const summary = useMemo(() => count + count2
  , [
    count,
    count2,
  ])

  return (
    <>
      <p>Hello World</p>
      <p>{`${name}${suffix}`}</p>
      <p style={{ color }}>{`${count}回押しました`}</p>
      <Button
        setCount={setCount}
      />
      <p>{`${count2}回押しました`}</p>
      <Button
        setCount={setCount2}
      />
      <p>{`合わせて${summary}回押しました`}</p>
    </>
  )
}

```

`src/component/index.js` を作り、component配下のモジュールをまとめてexportしておくと
後で取り出す時に便利。

```javascript
export { Button } from './Button'
export { Hello } from './Hello'
```


そして `src/App.js`

```javascript
import React from 'react'
import logo from './logo.svg'
import './App.css'
import {
  Hello,
} from './component'

const App = props => {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />

        <Hello name='hoge' suffix='様' />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  )
}

export default App
```



## ルーターを使った画面遷移

今まではずっと `localhost:3000/` の中でページを作っていた。

ここでは違うページに遷移してみる。
Reactは SPA(Single Page Application) という構成で作ることが多い。
SPAでは画面遷移する時に、全リロードするのではなく、
内部的に画面を切り替えるだけで実際にはリロードしないという構成になる。

これを簡単に実現する為、 `react-router-dom` というパッケージが提供されている。

`react-router-dom` は最初からは入っていないので、パッケージの追加をする。

パッケージを追加する場合はコマンドラインから `npm install` というコマンドを使って
追加することができる。

`npm install react-router-dom`

### トップページの変更

`App.js` にトップページを書いてきたが、これもRouterの配下に置きたいので
`src/component/Top.js` を作って移しておく

```javascript
import React from 'react'
import logo from '../logo.svg'
import {
  Hello,
} from '../component'

export const Top = props => {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />

        <Hello name='hoge' suffix='様' />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  )
}
```

`src/component/index.js` に `Top` コンポーネントのexportを追加

```javascript
export { Button } from './Button'
export { Hello } from './Hello'
export { Top } from './Top'

```

### ルートの設定


`src/Router.js` を作って、ページ遷移の設定を記述する

```javascript
import React from 'react'
import {
  BrowserRouter,
  Switch,
  Route,
} from 'react-router-dom'
import { Top } from './component'

export const Router = props => {

  return (
    <BrowserRouter>
      <Switch>
        <Route exact path='/' component={Top} />
      </Switch>
    </BrowserRouter>
  )
}

```

そして `src/App.js` は `Router` を呼ぶだけにする

```javascript
import React from 'react'
import './App.css'
import { Router } from './Router'

const App = props => {
  return (
    <div className="App">
      <Router />
    </div>
  )
}

export default App

```

これで今までと同じ動きの画面が出るはず。

ただ、 `Router` コンポーネントを経由するようになっているので
`Router` コンポーネントに別ページのルートを追加していくことで別ページを開くことができる。


### Profileページの作成

適当な別ページを作成して動作を確認する。
`src/component/Profile,js` を作成

```javascript
import React from 'react'

export const Profile = props => {
  return (
    <h1>Profileのページです</h1>
  )
}
```

`src/component/index.js` にも追加しておく

```javascript
export { Button } from './Button'
export { Hello } from './Hello'
export { Top } from './Top'
export { Profile } from './Profile'
```

`src/component/Router.js` に `Profile` へのルートを追加する

```javascript

import React from 'react'
import {
  BrowserRouter,
  Switch,
  Route,
} from 'react-router-dom'
import {
  Top,
  Profile,
} from './component'

export const Router = props => {

  return (
    <BrowserRouter>
      <Switch>
        <Route exact path='/' component={Top} />
        <Route exact path='/profile' component={Profile} />
      </Switch>
    </BrowserRouter>
  )
}


```

これでブラウザのURLから `http://localhost:3000/profile` を叩くとprofileページが表示される

### ナビゲーションバーの作成

メニューからのリンクをしたいので、ナビゲーションバーを置いてそこからリンクさせるようにする。
ナビゲーションバーはどのページでも表示すると想定して、`Router` コンポーネントに配置してみる

まず `src/component/Navigation.js` を作る

ページリンクは `Link` コンポーネントを使うことで実装できる


```javascript
import React from 'react'
import { Link } from 'react-router-dom'
import Logo from '../logo.svg'

export const Navigation = props => {

  return (
    <>
      <div style={styles.container}>
        <img
          style={styles.logo}
          src={Logo}
          alt='logo'
        />
        <Link to='/' style={styles.title}>
          <h2>React Demo</h2>
        </Link>
        <div style={styles.navContainer}>
          <Link to='/' style={styles.link}>
            <p style={styles.navItem}>Home</p>
          </Link>
          <Link to='/profile' style={styles.link}>
            <p style={styles.navItem}>Profile</p>
          </Link>
        </div>
      </div>
    </>
  )

}

const styles = {
  logo: {
    height: 30,
    marginLeft: 25
  },
  title: {
    fontWeight: 300,
    color: 'white',
    margin: 0,
    textAlign: 'left',
    marginLeft: 10,
  },
  navContainer: {
    display: 'flex',
    flex: 1,
    paddingLeft: 50,
    marginTop: 6
  },
  link: {
    textDecoration: 'none',
  },
  navItem: {
    marginLeft: 20,
    color: 'white',
    paddingBottom: '4px',
    borderBottom: '2px solid transparent',
    ':hover': {
      borderBottom: '2px solid white'
    }
  },
  container: {
    height: '80px',
    alignItems: 'center',
    width: '100%',
    backgroundColor: '#555500',
    display: 'flex'
  }
}

```

そして `src/Router.js` にNavigationを組み込む。

```javascript
import React from 'react'
import {
  BrowserRouter,
  Switch,
  Route,
} from 'react-router-dom'
import {
  Top,
  Profile,
  Navigation,
} from './component'

export const Router = props => {

  return (
    <BrowserRouter>
      <Navigation />
      <Switch>
        <Route exact path='/' component={Top} />
        <Route path='/profile' component={Profile} />
      </Switch>
    </BrowserRouter>
  )
}

```