React入門 1週間でReactをマスターする #04. 条件分岐(if)と繰り返し(loop)

# 目次
[1. Reactの新規プロジェクトの立ち上げ](https://qiita.com/items/2ae26050efd2133c2286)
[2. コンポーネントの書き方とイベントハンドラ](https://qiita.com/items/ca91e2f9905fb8ca62d0)
[3.Class Components と Function Components](https://qiita.com/yassun-youtube/items/2ed8601e4fa477726705)
[4. 条件分岐 (if) と繰り返し (loop)](https://qiita.com/yassun-youtube/items/9474b1681958e2ab0f25) <font color="Red">←今ここ</font>
[5. フォームと親子間のデータのやり取り](https://qiita.com/yassun-youtube/items/545e7d9c98fe919dc394)
[6. コンポーネントのライフサイクル](https://qiita.com/yassun-youtube/items/372464404ae6855e6d78)
7. スタイル (準備中)
8. Higher-Order Component (準備中)
9. Portalを利用したモーダル (準備中)
10. refによるエレメントの取得 (準備中)
11. Contextを利用したテーマの変更 (準備中)

# 今回の学習内容

今回は、

- JSX内での条件分岐(状態によっての表示切り替え)
- JSX内での項目の繰り返し表示

をやっていきます。

# YouTubeでの解説動画

YouTubeでも解説しています。
動画で確認したい方はこちらもどうぞ。
[【YouTube動画】 未経験から1週間でをマスターするReact入門 #04. React入門 1週間でReactをマスターする #04. 条件分岐(if)と繰り返し(loop)](https://youtu.be/ZLEMN2pCE8E)
[![【YouTube動画】 未経験から1週間でをマスターするReact入門](https://img.youtube.com/vi/ZLEMN2pCE8E/0.jpg)](https://youtu.be/ZLEMN2pCE8E)

# この記事のソースコード
ソースコードはGitHubで公開しています。

https://github.com/yassun-youtube/ReactTutorial

今回は下記コミットをやっていきます。

![スクリーンショット 2020-11-21 17.19.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/36959f12-4847-de4f-688d-fe4266ba3ed8.png)


# タブによる条件分岐

今回は、タブを作って、そのどのタブを表示しているかを状態で管理しておき、条件分岐をやってみます。

タブで `List.js` と `Form.js` の表示で入れ替えるようにしたいので、 `Form.js` を作成します。

```jsx:src/Form.js
export const Form = () => {
  return (
    <div>
      フォームです
    </div>
  )
}
```

これを `App.js` に追加します。

```jsx:src/App.js
import { useState } from 'react';
import { List } from "./List";
import { Form } from "./Form"; // 追加

function App() {
  const [description, setDescription] = useState('クリック前の表示');

  const changeDescription = () => {
    setDescription('クリック後の表示です。')
  }

  return (
    <div>
      { description }
      <List title="取り扱い言語一覧"/>
      <Form /> { /* 追加 */ }
      <button onClick={changeDescription}>ボタン</button>
    </div>
  );
}

export default App;
```

これで下図のように表示されます。

![_2020-11-01_19.06.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/7d5016d5-7702-c607-b82e-b1a64464944a.png)

続いて `App.js` にヘッダ部分を追加します。

デザインをまだ当てていないのでタブのようには見えませんが、タブとして扱います。

```jsx:src/App.js
import { useState } from 'react';
import { List } from "./List";
import { Form } from "./Form";

function App() {
  const [description, setDescription] = useState('クリック前の表示');

  const changeDescription = () => {
    setDescription('クリック後の表示です。')
  }

  return (
    <div>
      <header> { /* 追加 */ }
        <ul>
          <li>リスト</li>
          <li>フォーム</li>
        </ul>
      </header>
      <hr /> { // 追加 }
      { description }
      <List title="取り扱い言語一覧"/>
      <Form />
      <button onClick={changeDescription}>ボタン</button>
    </div>
  );
}

export default App;
```

これで下図のように表示されます。

![_2020-11-01_19.08.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/dc035834-22b2-9ef5-0742-487c4a1e5e71.png)


この `リスト` `フォーム` というのをタブとみなして、 `List.js` と `Form.js` の表示の状態を管理するようにしてみましょう。

```jsx:src/App.js
import { useState } from 'react';
import { List } from "./List";
import { Form } from "./Form";

function App() {
  const [description, setDescription] = useState('クリック前の表示');
  const [tab, setTab] = useState('list'); // 追加

  const changeDescription = () => {
    setDescription('クリック後の表示です。')
  }

  return (
    <div>
      <header>
        <ul>
          <li onClick={() => setTab('list')}>リスト</li>
          <li onClick={() => setTab('form')}>フォーム</li>
        </ul>
      </header>
      <hr />
      { description }
      { // 変更
        tab === 'list' ? <List title="取り扱い言語一覧"/> : <Form />
      }
      <button onClick={changeDescription}>ボタン</button>
    </div>
  );
}

export default App;
```

この変更で、ヘッダのリストの項目をクリックすることで内容が変わるようになりました。

![84e768c41ffd00c2d42fe0d9a34fe715.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/83ee3bf3-64f7-bfc1-6078-f171058dee70.gif)


## コード解説

コードの内容を見ていきましょう。

```jsx
  const [tab, setTab] = useState('list'); // 追加
```

新しく、こちらのコードを追加しました。

これは、 `tab` という state を定義しています。 初期値は `list` です。

```jsx
{ // 変更
  tab === 'list' ? <List title="取り扱い言語一覧"/> : <Form />
}
```

次にこちらの部分で表示を制御しています。

JSXでは、 `{}` は Javascript の値を入れられます。ここではその中で三項演算子を使って `tab` の状態で表示を分岐させていることがわかります。

Reactでは、このように条件分岐で画面の表示を変更することが可能です。

# 繰り返しによるリスト表示

次に、Reactによる繰り返しを見ていきます。

`List.js` に取り扱い言語のリストとなるステートを用意して、それをリスト表示させてみましょう。

```jsx:src/List.js
const LANGUAGES = [ // 追加
  'JavaScript',
  'C++',
  'Ruby',
  'Java',
  'PHP',
  'Go'
];

export const List = ({ title }) => {
  return (
    <div>
      <h4>{ title }</h4>
      { // 変更
        LANGUAGES.map((lang, index) => {
          return <div key={index}>{ lang }</div>
        })
      }
    </div>
  )
}
```

いくつかコードを追加してみました。

こちらのコードにより、下図のように表示が変わります。

![_2020-11-01_19.26.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/477f2214-2a22-91a2-eee3-30bda6cc0fc8.png)

## コード解説

```jsx
const LANGUAGES = [ // 追加
  'JavaScript',
  'C++',
  'Ruby',
  'Java',
  'PHP',
  'Go'
];
```

まず、言語リストの初期値として定数を定義しています。

```jsx
{
    LANGUAGES.map((lang, index) => {
      return <div key={index}>{ lang }</div>
    })
}
```

こちらのコードが繰り返しの部分です。

ここでは、 `map` 関数を使って `<div>` の配列を返しています。
Reactでは、繰り返しは基本的に `map` などの配列を返す関数を利用して行います。

> 繰り返しのTips
一つ注意しないといけないのは、繰り返しを行う際は、 繰り返される要素に `key` 属性を指定する必要があります。これは、Reactが繰り返された要素を区別するために必要なものなので、ユニークである必要があります。
無くても動きますが、コンソールにエラーが出ますし、予測不能なバグを生む可能性があるのでつけるようにしてください。

# 条件分岐、繰り返しまとめ

JSXでは、HTML（のようなもの）の中にコードが記載できるので、そこに 三項演算子や `map` などを利用して要素を返してやれば、条件分岐や繰り返しが可能になります。

JavaScriptを理解されている方なら、簡単に条件分岐や繰り返しが可能ですね。

# 次に向けた余計なコードの整理など

前回、 `App.js` 中で利用した `descrption` という state は、今後不要なので削除しておきます。

また、 `title` を `List.js`に `props` として渡していますが、こちらも不要なので削除します。

```jsx:src/App.js
import { useState } from 'react';
import { List } from "./List";
import { Form } from "./Form";

function App() {
  // descriptionを削除
  const [tab, setTab] = useState('list');

  return (
    <div>
      <header>
        <ul>
          <li onClick={() => setTab('list')}>リスト</li>
          <li onClick={() => setTab('form')}>フォーム</li>
        </ul>
      </header>
      <hr />
      { /* descriptionを削除 */ }
      {
        tab === 'list' ? <List /> : <Form /> // Listへのtitle属性を削除
      }
      { /* buttonを削除 */ }
    </div>
  );
}

export default App;
```

`App.js` から `description` に関連するコードと `List.js` への `title` 属性を削除しました。

次に、 `List.js` から `title` 属性を削除します。

```jsx:List.js
const LANGUAGES = [
  'JavaScript',
  'C++',
  'Ruby',
  'Java',
  'PHP',
  'Go'
];

export const List = () => { // title を削除
  return (
    <div>
      { /* h4 を削除(title表示) */ }
      {
        LANGUAGES.map((lang, index) => {
          return <div key={index}>{ lang }</div>
        })
      }
    </div>
  )
```

これできれいになりました。

この状態で入門5に行きたいと思います。


# 今日やったこと

## 条件分岐による表示切り替え

条件分岐は、三項演算子を使うことで表現できました。

```jsx
function Test() {
  return (
    <div>
      {
        tab === 'list' ? <List /> : <Form />
      }
    </div>
  )
}
```

こちらも可↓
`let` と `if` を使って入れる値を変えるというやり方でもできます。

```jsx
function Test() {
  const tabComponent = tab === 'list' ? <List /> : <Form />
  return (
    <div>
      { tabComponent }
    </div>
  )
}

```

## 繰り返しによるリスト表示

繰り返しは `map` 関数を使って表現しました。

```jsx
function Test() {
  return (
    <div>
      {
        list.map((val, i) => {
          return <div key={i}>{ val }</div>
        })
      }
    </div>
  )
}
```

# Class Componentsへの反映

ここからは、上記の内容を Class Componentsに適用していきます。

ブランチを `class-components` ブランチに切り替えて、 Class Components で今回の最終形の状態に持っていきます。

```bash
git checkout class-components
```

# Class Componentsへの反映

```jsx:src/App.js
import React from 'react';
import { List } from "./List";
import { Form } from "./Form";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { tab: 'list' };
  }
  render() {
    const { tab } = this.state;
    return (
      <div>
        <header>
          <ul>
            <li onClick={() => this.setState({ tab: 'list' })}>リスト</li>
            <li onClick={() => this.setState({ tab: 'form' })}>フォーム</li>
          </ul>
        </header>
        <hr />
        {
          tab === 'list' ? <List /> : <Form />
        }
      </div>
    )
  }
}

export default App;
```

```jsx:src/List.js
import React from 'react';

const LANGUAGES = [
  'JavaScript',
  'C++',
  'Ruby',
  'Java',
  'PHP',
  'Go'
];

export class List extends React.Component {
  render() {
    return (
      <div>
        {
          LANGUAGES.map((lang, index) => {
            return <div key={index}>{ lang }</div>
          })
        }
      </div>
    )
  }
}
```

```jsx:src/Form.js
import React from 'react';

export class Form extends React.Component {
  render() {
    return (
      <div>フォームです</div>
    )
  }
}
```

これでClass Component側にも反映できました。
同じことをClass Components側にもやることで、復習になります。

# おわりに

今日は条件分岐と繰り返しについて学びました。

次は、フォームと親子間のデータのやり取りについてお話していきます。

# 次の記事

React入門 未経験から1週間でReactをマスターする #05. フォームと親子間のデータのやり取り
https://qiita.com/yassun-youtube/items/545e7d9c98fe919dc394