Reactで簡易コーポレートサイトを作成する #2 -ナビゲーションバーとフッター編-

# 概要
Topページとお問合せページを分けて、ナビゲーションバーでページ間遷移できるようにします。
フッターも作成します。

# 完成イメージ
<img width="1686" alt="000001.jpg" src="https://dl.dropboxusercontent.com/s/jdtoypx6d8fw507/000001.jpg"><img width="1686" alt="000010.jpg" src="https://dl.dropboxusercontent.com/s/l1mu2sk8wm2eupc/000010.jpg">

# ナビゲーションバー作成
## Navbar/index.js
src/componentsに新たにNavbarというフォルダを作成し、その中にindex.jsとNavbar.cssを作成します。メニューバーに関する記述はこのNavbarフォルダ内の2つのファイルにしていきます。

```
mkdir src/components
mkdir src/components/Navbar
touch src/components/Navbar/index.js src/components/Navbar/Navbar.css
```

index.jsはReact Componentの基本的な構造を記述し、中身は[簡易コーポレートサイトを作成する](https://qiita.com/minimumskills/private/5bb8ce1c4236f14d882b#%E6%9C%80%E7%B5%82%E7%9A%84%E3%81%AA%E3%82%B3%E3%83%BC%E3%83%89)で作成したindex.htmlの中から`<nav>〜</nav>`をコピーして作成します。

```Navbar/index.js
import React from "react";

const Navbar = () => {
    return (
        <nav class="nav">
            <ul>
                <li><a href="./index.html">WebSite</a></li>
                <li><a href="./index.html">TOP</a></li>
                <li><a href="./contact.html">CONTACT</a></li>
            </ul>
        </nav>
    )
}
export default Navbar;
```

## Navbar/Navbar.css
コピペでスタイルを記述します。

```Navbar/Navbar.css
.nav {
    /* 背景色設定 */
    background-color: #666;
}

.nav ul {
    /* 表示幅を90%に */
    width: 90%;
    /* フレックスボックス化 */
    display: flex;
    /* 先頭のポチをなくす */
    list-style: none;
    /* 余白の自動調整 （上下の余白は0、左右は自動調整）*/
    margin: 0 auto;
    /* 高さを50pxに指定 */
    height: 50px;
}

.nav a {
    /* アンダーライン削除 */
    text-decoration: none;
    /* 文字色設定 */
    color: #fff;
    /* 内側余白を上右下左の順で設定 */
    padding: 10px 20px 10px 0px;
    /*ブロックにする */
    display: block;
    /* 文字を大き目に設定 */
    font-size: large;
}

.nav a:hover {
    /* マウスオーバーした時の文字色を設定 */
    color: #aaa;
}

/*スマホ対応*/
@media screen and (max-width: 640px) {
    .nav {
        background-color: #0183a0;
        height: 150px;
    }

    .nav ul {
        flex-direction: column;
        padding: 0;
    }

    .nav li {
        border-bottom: solid 1px #fff;
    }
}
```
## Navbar/index.js
cssのインポートとクラス属性をclassからclassNameに変更します。

```diff_javascript:Navbar/index.js
    import React from "react";
+   import './Navbar.css';

    const Navbar = () => {
        return (
-           <nav class="nav">
+           <nav className="nav">
                <ul>
                    <li><a href="./index.html">WebSite</a></li>
                    <li><a href="./index.html">TOP</a></li>
                    <li><a href="./contact.html">CONTACT</a></li>
                </ul>
            </nav>
        )
    }
    export default Navbar;
```

## App.js
App.jsに追加します。

```diff_javascript:App.js
    import './App.css';
    import Top from './screens/Top';
    import Contact from './screens/Contact';
+   import Navbar from './components/Navbar';

    function App() {
      return (
        <div className="App">
+         <Navbar />
          <Top />
          <Contact />
        </div>
      );
    }

    export default App;

```

保存して確認するとナビゲーションバーが追加されました。
<img width="1686" alt="000020.jpg" src="https://dl.dropboxusercontent.com/s/joc6ngoh7c3htgx/000020.jpg">


# フッター作成
同じ要領でフッターを作っていきます。

```
mkdir src/components/Footer
touch src/components/Footer/index.js src/components/Footer/Footer.css
```

## Footer/index.js

index.jsはReact Componentの基本的な構造を記述し、中身は[簡易コーポレートサイトを作成する](https://qiita.com/minimumskills/private/5bb8ce1c4236f14d882b#%E6%9C%80%E7%B5%82%E7%9A%84%E3%81%AA%E3%82%B3%E3%83%BC%E3%83%89)で作成したindex.htmlの中から`<footer>〜</footer>`をコピーして作成します。

```Footer/index.js
import React from "react";

const Footer = () => {
    return (
        <footer class="footer">
            &copy; 2022 bluecode, inc. All Rights Reserved.
        </footer>
    )
}
export default Footer;

```

## Footer/Footer.css
スタイルもコピペで記述します。

```Footer.css
.footer {
    background-color: #666;
    height: 60px;
    color: #fff;
    display: flex;
    justify-content: center;
    align-items: center;
    position: sticky;
    top: 100vh;
}
/*スマホ対応*/
@media screen and (max-width: 640px) {
    .footer {
        background-color: #0183a0;
    }
}
```

## Footer/index.js
インポートとクラス属性をclassNameに変更します。

```diff_javascript:Footer/index.js
    import React from "react";
+   import './Footer.css';

    const Footer = () => {
        return (
            <footer class="footer">
+           <footer className="footer">
                &copy; 2022 bluecode, inc. All Rights Reserved.
            </footer>
        )
    }
    export default Footer;

```

## App.jsで読み込み

```diff_javascript:App,js
    import './App.css';
    import Home from './screens/Home';
    import Contact from './screens/Contact';
    import Navbar from './components/Navbar';
+   import Footer from './components/Footer';

    function App() {
      return (
        <div className="App">
          <Navbar />
          <Home />
          <Contact />
+         <Footer />
        </div>
      );
    }

    export default App;
```
保存して確認します。
一番下に作成できていることが確認できます。
<img width="1686" alt="000030.jpg" src="https://dl.dropboxusercontent.com/s/2fupstomoxv40i6/000030.jpg">


# ナビゲーションの実装
ナビゲーションバーができましたが、まだ、TopとContactが同じ画面に表示されていて、ページ遷移ができておらず、ナビゲーションバーが機能していません。
ナビゲーションを実装していきます。

## react-router-domのインストール
コマンドラインからインストールをしていきます。
プロジェクトファイル内にいることを確認して下記を実行します。

```
npm install react-router-dom
```
インストールされたパッケージは、package.jsonで確認できます。
<img width="447" alt="000040.jpg" src="https://dl.dropboxusercontent.com/s/8zyudh1dmmv2n9z/000040.jpg">


## App.js
App.jsを編集します。
pathごとに表示するコンポーネントの出し分けをしています。
react-router関連のコンポーネントは全て`<BrowserRouter> 〜</BorwserRouter>`の中で使います。
`<Routes>〜</Routes>`の中に出し分けるコンポーネントを設定し、`<Route />`で設定をしていきます。path 属性と element 属性に適切な値を設定します。※共通部であるNavとFooterがRoutesの外に記述されているのがポイントです。

```diff_javascript:App.js
  import './App.css';
+ import { BrowserRouter, Routes, Route } from 'react-router-dom';

  import Top from './screens/Top';
  import Contact from './screens/Contact';
  import Navbar from './components/Navbar';
  import Footer from './components/Footer';

  function App() {
    return (
      <div className="App">
+       <BrowserRouter>
          <Navbar />
-         <Top />
-         <Contact />
+         <Routes>
+           <Route path="/" element={<Top />} />
+           <Route path="/contact" element={<Contact />} />
+         </Routes>
          <Footer />
+       </BrowserRouter>
      </div>
    );
  }

  export default App;
```

```javascript:コピペ用
<BrowserRouter>
  <Navbar />
  <Routes>
    <Route path="/" element={<Top />} />
    <Route path="/contact" element={<Contact />} />
  </Routes>
  <Footer />
</BrowserRouter>
```
保存したら、http://localhost:3000 、http://localhost:3000/contact にアクセスしてそれぞれ表示されているか確認します。
> ナビゲーションのリンクはhtmlのままなのでうまく動作しません。上記をURLに入力して動作確認してください。

<img width="500" alt="000050.jpg" src="https://dl.dropboxusercontent.com/s/2npg7v7ftbmio88/000050.jpg"><img width="500" alt="000060.jpg" src="https://dl.dropboxusercontent.com/s/t95su8jcrou4pc1/000060.jpg">



中身の切り分けが確認できました。

# Navbar/index.jsの編集
次に、まだナビゲーションバーのリンクが設定できていないのでNavbarコンポーネントを編集して、Homeのパス、Contactのパスを設定します。
react-router-domのNavLinkを使って記述します。
styleで記述しているのは指定しているpathが表示されている場合の文字色を設定しています。

```diff_javascript:Navbar/index.js
  import React from "react";
  import './Navbar.css';
+ import { NavLink } from "react-router-dom";

  const Navbar = () => {
      return (
          <nav className="nav">
              <ul>
-                 <li><a href="./index.html">WebSite</a></li>
-                 <li><a href="./index.html">TOP</a></li>
-                 <li><a href="./contact.html">CONTACT</a></li>
+                 <li><NavLink to="/">WebSite</NavLink></li>
+                 <li><NavLink to="/">TOP</NavLink></li>
+                 <li><NavLink to="/contact">CONTACT</NavLink></li>
              </ul>
          </nav>
      )
  }
  export default Navbar;
```

```javascript:コピペ用
<li><NavLink to="/">WebSite</NavLink></li>
<li><NavLink to="/">TOP</NavLink></li>
<li><NavLink to="/contact">CONTACT</NavLink></li>
```
保存して確認します。
見た目は変わりませんがそれぞれ、ナビゲーションバーから画面遷移ができるようになりました。

# 最終的なコード
## components/Navbar/index.js

```components/Navbar/index.js
import React from "react";
import { NavLink } from "react-router-dom";

import './Navbar.css';

const Navbar = () => {
    return (
        <nav className="nav">
            <ul>
                <li><NavLink to="/">WebSite</NavLink></li>
                <li><NavLink to="/">TOP</NavLink></li>
                <li><NavLink to="/contact">CONTACT</NavLink></li>
            </ul>
        </nav>
    )
}
export default Navbar;
```
## components/Navbar/Navbar.css

```components/Navbar/Navbar.css
.nav {
    /* 背景色設定 */
    background-color: #666;
}

.nav ul {
    /* 表示幅を90%に */
    width: 90%;
    /* フレックスボックス化 */
    display: flex;
    /* 先頭のポチをなくす */
    list-style: none;
    /* 余白の自動調整 （上下の余白は0、左右は自動調整）*/
    margin: 0 auto;
    /* 高さを50pxに指定 */
    height: 50px;
}

.nav a {
    /* アンダーライン削除 */
    text-decoration: none;
    /* 文字色設定 */
    color: #fff;
    /* 内側余白を上右下左の順で設定 */
    padding: 10px 20px 10px 0px;
    /*ブロックにする */
    display: block;
    /* 文字を大き目に設定 */
    font-size: large;
}

.nav a:hover {
    /* マウスオーバーした時の文字色を設定 */
    color: #aaa;
}

/*スマホ対応*/
@media screen and (max-width: 640px) {
    .nav {
        background-color: #0183a0;
        height: 150px;
    }

    .nav ul {
        flex-direction: column;
        padding: 0;
    }

    .nav li {
        border-bottom: solid 1px #fff;
    }
}
```
## components/Footer/index.js

```components/Footer/index.js
import React from "react";
import './Footer.css';

const Footer = () => {
    return (
        <footer className="footer">
            &copy; 2022 bluecode, inc. All Rights Reserved.
        </footer>
    )
}
export default Footer;

```
## components/Footer/Footer.css

```components/Footer/Footer.css
.footer {
    background-color: #666;
    height: 60px;
    color: #fff;
    display: flex;
    justify-content: center;
    align-items: center;
    position: sticky;
    top: 100vh;
}

/*スマホ対応*/
@media screen and (max-width: 640px) {
    .footer {
        background-color: #0183a0;
    }
}
```
## App.js

```App.js
import './App.css';
import { BrowserRouter, Routes, Route } from 'react-router-dom';

import Top from './screens/Top';
import Contact from './screens/Contact';
import Navbar from './components/Navbar';
import Footer from './components/Footer';

function App() {
  return (
    <div className="App">
      <BrowserRouter>
        <Navbar />
        <Routes>
          <Route path="/" element={<Top />} />
          <Route path="/contact" element={<Contact />} />
        </Routes>
        <Footer />
      </BrowserRouter>
    </div>
  );
}

export default App;
```


# 関連コンテンツ
- 次：[Reactで簡易コーポレートサイトを作成する #3 -バリデーションとビルド編-](https://qiita.com/minimumskills/private/b2d0d66068b5047d1f3f)
- 前：[Reactで簡易コーポレートサイトを作成する #1 -Top/Contactコンポーネント編-](https://qiita.com/minimumskills/private/da37eaf8f188095e1feb)