format_list_bulleted
【React.js】Reactでコンポーネントを使ってみる(React 入門)
最終更新日時:2020-05-16 02:26:50



Reactを使って開発することのメリットの一つにコンポーネントでフロント画面のパーツを作って再利用できることにあります。今回はReactでコンポーネントを使う方法を説明します。本記事はコンポーネントについて聞いたことあるはあるけど使ったことない人や、Vueなどでコンポーネント使ったことあるけどReactでは使ったことない人を対象にしています。

本記事の前提

本記事はcreaate react appコマンドで作成していること前提にしています。Webpackなどのモジュールバンドラを導入している前提です。また、以下の知識を前提としています。

  • Node.js 8.1以上とnpm 5.6以上がインストールされている
  • create react appでのプロジェクトの立ち上げが(なんとなく)わかる
  • JavaSceriptのクラスの使い方について(なんとなく)わかる
  • import文、export文が(なんとなく)わかる

JavaScriptのクラスについては「クラスの書き方・使い方について解説」を参考にするといいと思います。

作成する画面

今回は以下のような画面を実装します。

ボタンを押すとカウントが増えていくだけの画面です。こんなシンプルな画面ですが、3つのコンポーネントで丁寧に作ります。作成するコンポーネントは以下の表にまとまっています。

コンポーネント名役割
TopPageページ全体の要素
CountDisplayカウントを表示する部分
AddButtonカウントアップをするボタン

作成手順

作成手順は以下のようになります。

  1. create react appでプロジェクトの立ち上げ
  2. publicフォルダ、srcフォルダの整理
  3. index.html, index.jsの編集
  4. 各コンポーネントの作成
  5. stateとpropの指定
  6. イベントハンドリングの指定

今回使用したコードはcode-databaseのgithubリポジトリにも公開されていますので、手元で確認したい方は参考にしてみてください。

実際に作ってみる

先ほどの手順に則って機能を作っていきましょう!

create react appでプロジェクトの立ち上げ

まずはプロジェクトを立ち上げます。以下のコマンドでプロジェクトフォルダを作成しましょう。

タイトル:ターミナル

$ npx create-react-app sample-app

create-react-appコマンドがglobalインストールされている方はエラーが起きる可能性があります。npm uninstall -g create-react-appでアンインストールしましょう。アンストールができない場合もあります。その場合はwhich craete-react-appで表示されるファイルを直接削除してみましょう。

publicフォルダ、srcフォルダの整理

プロジェクトフォルダができたらデフォルトで入っているpublicフォルダとsrcフォルダ内のファイルで不要なものを削除します。publicフォルダ内のindex.html、srcフォルダ内のindex.js以外は削除してしまいましょう。

続いてsrcフォルダ内にpagesフォルダとcomponentsフォルダを作成します。pagesフォルダにはページのコンポーネントを、componentsフォルダにはページ内の部品となるコンポーネントを作成することにします(フォルダの分け方に特に指定はありません)。

さらに、pagesフォルダとcomponentsフォルダにコンポーネントを記述するファイル(TopPage.js, CountDisplay.js, AddButton.js)を作成します。ここまでの整理でディレクトリ構造は次のようになっています。

タイトル:フォルダ階層

sample-app/
 ├ node_modules/
 ├ public/
 │ └ index.html
 ├ src/
 │ ├ pages/
 │ │ └ TopPage.js
 │ ├ components/
 │ │ ├ CountDisplay.js
 │ │ └ AddButton.js
 │ └ index.js

index.html, index.jsの編集

続いて先ほど残したindex.htmlとindex.jsファイルを編集します。まずはindex.htmlを編集しましょう。

タイトル:index.html

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <title>sample-app</title>
</head>
<body>
  <div id='root'></div>
</body>
</html>

div#rootのみをbody内に記述するだけで大丈夫です。続いてindex.jsを編集します。

タイトル:index.js

import React from 'react'
import ReactDOM from 'react-dom';
import TopPage from './pages/TopPage.js'

ReactDOM.render(
    React.createElement(TopPage),
    document.getElementById('root')
);

index.jsにはTopPageを読み込み、これを先ほどhtmlファイルで指定したdiv#rootに描画する処理を記述します。

ReactDOM.renderというメソッドを用いて実際のDOMに変更を適用します。renderメソッドの第一引数には描画する要素を指定しますが、今回はReact.createElementメソッドで生成された要素を指定します。createElementメソッドは引数にコンポーネントなどを指定して要素を生成するメソッドです。renderメソッドの第二引数にはDOMの描画を行うhtml要素を指定します。

各コンポーネントの作成

本記事のメインテーマになっているコンポーネントを作成していきましょう。まずはTopPageを作成します。

タイトル:TopPage.js

import React from 'react'
import CountDisplay from '../components/CountDisplay'
import AddButton from '../components/AddButton'

export default class TopPage extends React.Component{
    render() {
        return (
            <div>
                <CountDisplay/>
                <AddButton/>
            </div>
        )
    }
}

CountDisplayとAddButtonをそれぞれインポートしてrenderメソッドで表示をしています。CountDisplayとAddButtonについてもrenderメソッドでhtml要素をJSXで記述します。

タイトル:CountDisplay.js

import React from 'react'

export default class CountDisplay extends React.Component {
    render() {
        return (
            <div>カウント:</div>
        ) 
    }
}

タイトル:AddButton.js

import React from 'react'

export default class AddButton extends React.Component{
    render() {
        return (
            <button>add</button>
        )
    }
}

stateとpropの指定

TopPageにstateを持たせてカウントを状態として保存できるようにします。さらにこのカウントをCountDisplayに渡して表示ができるようにします。まずはTopPageにstateを持たせるようにしましょう。

タイトル:TopPage.js

export default class TopPage extends React.Component{
    //追記
    constructor(props) {
        super(props)
        this.state = {
            count :0
        }
    }
    render() {
        return (
            <div>
                <CountDisplay count={this.state.count}/> //追記
                <AddButton/>
            </div>
        )
    }
}

constructorメソッドでstateを定義して、countというstateを作成して初期値を0に指定します。

さらにCountDisplayにデータを渡すために<CountDisplay count={this.state.count}/>を記述します。次にCountDsplay渡したcountをpropsとして受け取ります。

タイトル:CountDisplay.js

render() {
    return (
        <div>カウント:{ this.props.count }</div> //追記
    ) 
}

上記のようにpropsで受け取ったデータを使用することができます。

イベントハンドリングの指定

最後にAddButtonでボタンをクリックするとcountが増えるようにするため、AddButtonのクリックイベントをTopPageでハンドリングできるようにしましょう。

タイトル:TopPage.js

export default class TopPage extends React.Component{
    constructor(props) {
        super(props)
        this.state = {
            count :0
        }
        this.addCount = this.addCount.bind(this) //追記
    }
    //追記
    addCount() { 
        this.setState((state) => {
            return {
                count : state.count + 1
            }
        })
    }
    render() {
        return (
            <div>
                <CountDisplay count={this.state.count}/>
                <AddButton onAddCount={this.addCount}/> //追記
            </div>
        )
    }
}

まずはaddCountメソッドを定義してsetStateメソッドでcountを一つ増やすためのハンドラを用意します。この際にthis.addCount = this.addCount.bind(this)をconstructorメソッド内に記述してaddCountメソッドでのthisでTopPageを参照できるようにします。この記述がないとaddCountメソッド内でのthisがundefinedになってしまします。作成したaddCountメソッドは<AddButton onAddCount={this.addCount}/>でpropsと同じようにしてAddButtonに渡します。

タイトル:AddButton.js

export default class AddButton extends React.Component{
    //追記
    constructor(props) {
        super(props)
        this.handleClick = this.handleClick.bind(this);
    }
    //追記
    handleClick() {
        this.props.onAddCount()
    }
    render() {
        return (
            <button onClick={this.handleClick}>add</button> //追記
        )
    }
}

続いてAddButtonで先ほどonAddCountとして渡されたメソッドをAddButtonで定義したhandleClickメソッドを介して使用できるようにします。こちらでもconstructorメソッド内でthisをbindするのを忘れないようにしましょう。

お疲れ様でした!これで全ての機能を実装できました。

タイトル:ターミナル

$ npm run start

上のコマンドでローカルホストを立ち上げて正常に動くか確認してみましょう。

上のように機能すれば問題ないです。

この記事のまとめ

今回はカウントアップアプリを題材にReactのコンポーネントを説明しました。最後の記事の要点をまとめておきましょう。

  • コンポーネントを使うことでページの要素を再利用しながら作成できる
  • stateでコンポーネントの状態を扱うことができる
  • propsでコンポーネント間の値渡しを行うことができる
  • propsでメソッドも渡すことができる

皆さんもReactでコンポーネントを活用しましょう!