Help us understand the problem. What is going on with this article?

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

目次

1. Reactの新規プロジェクトの立ち上げ
2. コンポーネントの書き方とイベントハンドラ
3.Class Components と Function Components
4. 条件分岐 (if) と繰り返し (loop) ←今ここ
5. フォームと親子間のデータのやり取り (近日公開!)
6. コンポーネントのライフサイクル (準備中)
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)
【YouTube動画】 未経験から1週間でをマスターするReact入門

この記事のソースコード

ソースコードはGitHubで公開しています。

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

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

スクリーンショット 2020-11-21 17.19.40.png

タブによる条件分岐

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

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

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

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

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

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

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

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

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

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

コード解説

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

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

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

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

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

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

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

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

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

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

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

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

コード解説

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

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

{
    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 は、今後不要なので削除しておきます。

また、 titleList.jsprops として渡していますが、こちらも不要なので削除します。

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 属性を削除します。

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に行きたいと思います。

今日やったこと

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

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

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

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

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

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

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

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

Class Componentsへの反映

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

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

git checkout class-components

Class Componentsへの反映

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;
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>
    )
  }
}
src/Form.js
import React from 'react';

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

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

おわりに

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

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

yassun-youtube
教育系エンジニアやっすんがエンジニアに役立つTipsを毎日紹介するYouTubeチャンネル「やっすんのエンジニア大学」をやっています。 エンジニアリングに興味のある方全員が知って得するTIPSをお届けしています!
https://www.youtube.com/channel/UCajrdoGzHzDogrNrLYYmGsg/
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