Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

React Basic

概要

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

React

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

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

事前準備

JavaScriptの基本

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

JavaScriptBasicへのリンク

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

環境構築

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

node のインストール

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

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

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

node --version

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

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

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

Nodistのインストール

githubにインストーラーが用意されているので
ダウンロードしてインストールする。

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

nodist + 12.16.3

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

nodist 12.16.3

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

node --version

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

テキストエディタの準備

atom を使う。

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

公式 からインストールする。

インストールできたら、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にはない)
npxnpm install -g でグローバルパッケージをインストールしてから実行するコマンドについて
ローカルにインストールすることなく実行することができる便利なコマンド。
これを使うことで、グローバルパッケージのバージョンが古いとかの問題を回避することができる。

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

cd react-training
npm start

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

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

最初のReactコーディング

atomでソースコードを開く

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

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

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

App.js をいじってみる

src/App.js を開く。

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

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

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

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

Function Component

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

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

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

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が適用された状態になる。簡単。

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

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

defaultimport する時に名前を指定しない場合は 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を返すようにする

const Hello = props => {

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

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

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

こんな感じにする

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をセットする

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

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

const Hello = props => {

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

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

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

イベントをつけてみる

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

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

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

}

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

const Hello = props => {

  const {
    name,
    suffix,
  } = props

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

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

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

const Button = props => {

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

}

stateを使ってみる

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

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

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

import React, { useState } from 'react'

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 は 戻り値に配列を返し、第1要素に現在の値、第2要素の値を更新する為のメソッドを返す。

なので 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を把握する必要があるが
countButton コンポーネントで定義している為、 Hello からは見えない。

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

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

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

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

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

やってみる

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を使った副作用を実装する

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

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

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

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

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

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

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

メモ関数を使ってみる

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

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

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}
      />
    </>
  )
}

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

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

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

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

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と同じように第1引数に値が変わった時の関数、
第2引数に監視する値の配列を受ける。
useMemoはuseEffectと違って戻り値を持っていて、この戻り値には第1引数が返した値が入っている。

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

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

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

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

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

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

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

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

App.jsApp やら Hello やら Button やらの定義をしてきた。

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

これも importexport 機構を使えば簡単にできる。

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

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

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 を作り、以下のようにする

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しておくと
後で取り出す時に便利。

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

そして src/App.js

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 を作って移しておく

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.jsTop コンポーネントのexportを追加

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

ルートの設定

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

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.jsRouter を呼ぶだけにする

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 を作成

import React from 'react'

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

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

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

src/component/Router.jsProfile へのルートを追加する

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 コンポーネントを使うことで実装できる

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を組み込む。

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>
  )
}

AkihiroTakamura
仕事でやったことを問題ない範囲で気ままに上げていきます web系多し
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away