ウェブサイト検索

Reactでタブコンポーネントを作成する方法


紹介

もしウェブアプリを作ったことがあるなら、ある時点でタブ付き文書インターフェースを作成した可能性が高いです。タブは、複雑なインターフェースをユーザーが迅速に切り替えられるような管理可能なサブセクションに分割することを可能にします。タブは一般的なUIコンポーネントであり、実装方法を理解することが重要です。

この記事では、独自に使用することも既存のコンポーネントと一緒に使用することもできる再利用可能なタブコンテナコンポーネントの作成方法を学びます。

前提条件

このガイドを始める前に、次のものが必要です:

  • Node.jsを実行する開発環境が必要です。macOSまたはUbuntu 18.04にこれをインストールするには、macOSでNode.jsをインストールしてローカル開発環境を作成する方法や、Ubuntu 18.04にNode.jsをインストールする方法の PPAを使用したインストールセクションの手順に従ってください。
  • このチュートリアルでは、Create React Appを使用してアプリを作成します。Create React Appを使用してアプリケーションをインストールする手順は、「Create React Appを使用してReactプロジェクトを設定する方法」で見つけることができます。
  • JavaScriptの基本知識も必要であり、それは「JavaScriptでのコーディング方法」で見つけることができます。また、HTMLとCSSの基本知識も必要です。HTMLとCSSについては、Mozilla Developer Networkが良いリソースです。

このチュートリアルは、Node.js バージョン 10.20.1 と npm バージョン 6.14.4 でテストされました。

ステップ1 — 空のプロジェクトを作成する

このステップでは、Create React Appを使用して新しいプロジェクトを作成します。その後、プロジェクトをブートストラップするときにインストールされるサンプルプロジェクトと関連ファイルを削除します。

まず、新しいプロジェクトを作成します。ターミナルで、以下のスクリプトを実行して、create-react-appを使用して新しいプロジェクトをインストールしてください:

  1. npx create-react-app react-tabs-component

プロジェクトが完了したら、ディレクトリに移動してください:

  1. cd react-tabs-component

新しいターミナルのタブまたはウィンドウで、Create React Appのスタートスクリプトを使用してプロジェクトを開始します。ブラウザは変更に応じて自動的にリフレッシュされるので、作業中はこのスクリプトを実行したままにしておいてください:

  1. npm start

これにより、ローカルで実行されるサーバーが開始されます。プロジェクトがブラウザウィンドウで開かなかった場合は、http://localhost:3000/を訪れることで開くことができます。リモートサーバーからこれを実行している場合、アドレスはhttp://your_domain:3000になります。

あなたのブラウザは、Create React App の一部として含まれるテンプレート React アプリケーションで読み込まれます。

あなたは完全に新しいカスタムコンポーネントのセットを構築するので、空のプロジェクトを作成できるように、まずいくつかのボイラープレートコードを削除する必要があります。

まず、テキストエディタでsrc/App.jsを開きます。これはページに挿入されるルートコンポーネントです。すべてのコンポーネントはここから始まります。App.jsに関する詳細は、「Create React AppでのReactプロジェクトの設定方法」をご覧ください。

あなたはこのようなファイルを見るでしょう:

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

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <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;

行 import logo from './logo.svg'; を削除してください。次に、return ステートメント内のすべてを置き換えて、いくつかの div タグと h1 を返すようにしてください。これにより、Tabs Demo を表示する h1 を返す有効なページが得られます。最終的なコードは次のようになります:

import React from 'react';
import './App.css';

function App() {
  return (
    <div>
      <h1>Tabs Demo</h1>
    </div>
  );
}

export default App;

テキストエディタを保存して終了します。

最後に、ロゴを削除してください。アプリケーションでは使用しないので、作業中に未使用のファイルは削除するべきです。長い目で見れば、混乱を避けることができます。

ターミナルウィンドウに次のコマンドを入力してロゴを削除します:

  1. rm src/logo.svg

プロジェクトがセットアップされたので、最初のコンポーネントを作成できます。

ステップ2 — Tabsコンポーネントの作成

このステップでは、新しいフォルダーと各タブをレンダリングする Tabs コンポーネントを作成します。

まず、srcディレクトリにcomponentsというフォルダーを作成します:

  1. mkdir src/components

componentsフォルダーの中にTabs.jsという新しいファイルを作成します:

  1. nano src/components/Tabs.js

新しい Tabs.js ファイルに次のコードを追加してください:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Tab from './Tab';

これらは、このコンポーネントを作成するために必要なインポートです。このコンポーネントは、どのタブがアクティブであるかを追跡し、タブのリストとアクティブなタブのコンテンツを表示します。

次に、状態を追跡し、Tabs.jsのimportsの下にアクティブなタブを表示するために使用される以下のコードを追加します。

...

class Tabs extends Component {
  static propTypes = {
    children: PropTypes.instanceOf(Array).isRequired,
  }

  constructor(props) {
    super(props);

    this.state = {
      activeTab: this.props.children[0].props.label,
    };
  }

  onClickTabItem = (tab) => {
    this.setState({ activeTab: tab });
  }

...

アクティブタブに対して初期状態が追加され、あなたが作成するタブの配列では 0 から始まります。

onClickTabItem は、ユーザーによってクリックされた現在のタブにアプリの状態を更新します。

これで、レンダーファンクションを同じファイルに追加できます:

...

  render() {
    const {
      onClickTabItem,
      props: {
        children,
      },
      state: {
        activeTab,
      }
    } = this;

    return (
      <div className="tabs">
        <ol className="tab-list">
          {children.map((child) => {
            const { label } = child.props;

            return (
              <Tab
                activeTab={activeTab}
                key={label}
                label={label}
                onClick={onClickTabItem}
              />
            );
          })}
        </ol>
        <div className="tab-content">
          {children.map((child) => {
            if (child.props.label !== activeTab) return undefined;
            return child.props.children;
          })}
        </div>
      </div>
    );
  }
}

export default Tabs;

このコンポーネントは、どのタブがアクティブであるかを追跡し、タブのリストとアクティブなタブのコンテンツを表示します。

Tabsコンポーネントは、次に作成するTabコンポーネントを使用します。

ステップ3 — Tabコンポーネントの作成

このステップでは、個々のタブを作成するために使用するTabコンポーネントを作成します。

componentsフォルダー内にTab.jsという新しいファイルを作成してください:

  1. nano src/components/Tab.js

Tab.jsファイルに以下のコードを追加してください:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

再び、あなたは react から React をインポートし、PropTypes をインポートします。PropTypes はコンポーネントの props に対して型チェックを実行するために使用される特別な propTypes プロパティです。

次に、import文の下に次のコードを追加してください。

...
class Tab extends Component {
  static propTypes = {
    activeTab: PropTypes.string.isRequired,
    label: PropTypes.string.isRequired,
    onClick: PropTypes.func.isRequired,
  };

  onClick = () => {
    const { label, onClick } = this.props;
    onClick(label);
  }

  render() {
    const {
      onClick,
      props: {
        activeTab,
        label,
      },
    } = this;

    let className = 'tab-list-item';

    if (activeTab === label) {
      className += ' tab-list-active';
    }

    return (
      <li
        className={className}
        onClick={onClick}
      >
        {label}
      </li>
    );
  }
}

export default Tab;

このコンポーネントのPropTypesは、activeTabとlabelが文字列であり、必須であることを保証するために使用されます。onClickは、必須の関数として設定されています。

このTabコンポーネントはタブの名前を表示し、タブがアクティブな場合には追加のクラスを追加します。クリックすると、コンポーネントはonClickハンドラを発火させ、Tabsコンポーネントにどのタブがアクティブであるべきかを知らせます。

ステップ4 — アプリのスタイルを整えるためにCSSを追加する

コンポーネントを作成することに加えて、タブの外観を持たせるためにCSSを追加します。

App.cssファイル内のすべてのデフォルトのCSSを削除し、このコードを追加してください。

[label react-tabs-component/src/App.css] .tab-list {
  border-bottom: 1px solid #ccc;
  padding-left: 0;
}

.tab-list-item {
  display: inline-block;
  list-style: none;
  margin-bottom: -1px;
  padding: 0.5rem 0.75rem;
}

.tab-list-active {
  background-color: white;
  border: solid #ccc;
  border-width: 1px 1px 0 1px;
}

これにより、タブがインラインになり、クリックされたときにアクティブタブに境界線が付けられて目立つようになります。

ステップ5 — App.jsの更新

コンポーネントと関連するスタイルが整ったので、Appコンポーネントを更新してそれらを使用できるようにしてください。

まず、インポートを更新してTabsコンポーネントを含めてください:

import React from 'react';
import Tabs from "./components/Tabs";
import "./App.css";

次に、返り値のステートメントのコードを更新して、インポートされたTabsコンポーネントを含めます:

...

function App() {
  return (
    <div>
      <h1>Tabs Demo</h1>
      <Tabs>
        <div label="Gator">
          See ya later, <em>Alligator</em>!
        </div>
        <div label="Croc">
          After 'while, <em>Crocodile</em>!
        </div>
        <div label="Sarcosuchus">
          Nothing to see here, this tab is <em>extinct</em>!
        </div>
      </Tabs>
    </div>
  );
}

export default App;

divと関連するラベルは、タブにそのコンテンツを与えます。

App コンポーネントに Tabs を追加すると、セクション間を切り替えることができる動作するタブインターフェースが得られます。

このGithubリポジトリを見れば、完成したコードを見ることができます。

結論

このチュートリアルでは、Reactを使用してアプリケーションの状態を管理および更新するタブコンポーネントを構築しました。

ここから、Reactコンポーネントをスタイリングする他の方法を学び、さらに魅力的なUIを作成することができます。

Reactでの開発についてさらに学ぶために、DigitalOceanでの『How To Code in React.js』シリーズ全体をフォローすることもできます。

関連記事: