特集
» 2016年07月28日 05時00分 UPDATE

いまさら聞けないReact、Virtual DOM、JSX超入門 (1/3)

Facebookが公開しているJavaScriptライブラリ「React」について、その概要や特徴、Webページに導入する方法や基本的な使い方を解説します。

[諏訪悠紀,クラスメソッド]

Reactとは――その3つの特徴

 「React」はFacebookが公開している、ユーザーインタフェース(以下、UI)を効率的に構築することを目的としたWebフロントエンドフレームワーク(JavaScriptライブラリ)です。

 Reactには、次のような特徴があります。

シンプル

 Reactを使ってUIを実装すると、「アプリケーションがどのように見えるか」を単純に表現できます。

叙述的

 コンポーネントの状態がReactによって管理され、データに変更があるときには更新の必要があるコンポーネントだけ更新されるようになります。そのため、効率的にレンダリングさせることができます。

コンポーネントベース

 「状態」の管理がカプセル化されたコンポーネントを使って、複雑なUIを構築することができます。コンポーネントの組み合わせでアプリケーションを構築することにより、コードの再利用やテストなどを実施しやすくなります。

 本記事では、これらの特徴をもう少し詳細に理解するために、WebページにReactを導入する方法と基本的な使い方について解説します。

Reactを使うための準備

 ReactをWebアプリケーションに導入するには、次のような方法があります。

  • CDN(Contents Delivery Network)を参照する
  • スターターキットをダウンロードする
  • Webフロントエンド向けパッケージマネジャー「Bower」で管理する
  • Node.jsのパッケージマネジャー「npm」で管理し、「browserify」や「webpack」で変換する

 これらの導入方法は一例ですので、導入したいWebアプリケーションの環境に合った導入方法を選んでください(例えばRails向けには「react-rails」が用意されています)。

 ここでは、最もシンプルなCDNを参照する方法を紹介します。Reactのコアライブラリである「react」、それからDOMライブラリである「react-dom」を導入します。なお、ここでは開発用途で提供されているファイルを参照します。

 まずは、「index.html」ファイルを新しく作成し、「body」タグの中に次の2つの「script」タグを書いてください。

<!-- コアライブラリ -->
<script src="https://fb.me/react-15.2.0.js"></script>
<!-- DOMライブラリ -->
<script src="https://fb.me/react-dom-15.2.0.js"></script>

 これだけで、Webページ内でReactを使うための最低限の準備は終わりです。

Reactを使うための基礎知識

コンポーネントとエレメントとVirtual DOM

 Reactでは「コンポーネント」を生成し組み合わせていくことでUIを構築していきます。コンポーネントはデフォルトで用意されているものもあれば、自分で定義することもできます。またコンポーネントは直接使用するのではなく、インスタンス化して使います。このコンポーネントのインスタンスのことを「エレメント」といいます。

 ここで、まずは簡単な例を見てみましょう。次のコードでは、エレメントを生成しています。

var root = React.createElement('div');

 ここで指定している「div」は実際のDOMにおける「div」タグを示しているものではなく、Reactが標準機能として提供している「div」コンポーネントを示しています。つまり「React.createElement」を通して生成したエレメントは、実際のDOMノードではありません。エレメントはReactが管理するコンポーネントのインスタンスであり、実際のDOMノードへの描画はReactが必要に応じて行います。

 このように、Reactではコンポーネントやエレメントといった仮想的なDOMを通してUIを構築します。この仮想的なDOMのことを「Virtual DOM」といいます。

エレメントの生成と描画

 まずは、非常に簡単なエレメントの生成と描画から始めてみましょう。次のコードを書いてください。

<!-- 管理対象の要素 -->
<div id="content"></div>
 
<!-- コアライブラリ -->
<script src="https://fb.me/react-15.2.0.js"></script>
<!-- DOMライブラリ -->
<script src="https://fb.me/react-dom-15.2.0.js"></script>
 
<script type="text/javascript">
// エレメントの生成
var helloElement = React.createElement(
    "div", null, "Hello!"
);
// 描画
ReactDOM.render(helloElement, content);
</script>

 このコードでは、「Hello!」という文字列が含まれる「div」エレメントを生成し、IDが「content」であるDOMノードの中に描画しています。

 「React.createElement」の第1引数にはコンポーネント名、第2引数にはプロパティとして扱われるオブジェクト、第3引数以降は子のエレメントを渡します。第2引数については後述しますが、ここでは「null」を渡しています。

 「ReactDOM.render」を呼び出すと、Reactに実際のDOMノードへの描画を指示できます。第1引数にはReactのエレメント、第2引数には描画先となる実際のDOMノードのIDを指定します。

エレメントの生成の動作確認

コンポーネントの定義

 ここまでは「div」コンポーネントを使ってきましたが、コンポーネントを新しく定義することもできます。次のコードを書いてみましょう。

// コンポーネントの定義
var HelloClass = React.createClass({
    render: function() {
        return React.createElement(
            "div", null, "Hello!"
        );
    }
});
// エレメントの生成
var helloElement = React.createElement(HelloClass);
// 描画
ReactDOM.render(helloElement, content);

 コンポーネントを新しく定義するには「React.createClass」を呼びます。引数には「render」を持つオブジェクトを渡す必要があります。

 「render」には、戻り値としてエレメントを返す関数をセットします。ここでは「div」エレメントを生成して返しています。

 新しく定義した「HelloClass」は「div」と同様、コンポーネントの1つです。定義したコンポーネントを元にエレメントを生成するには「React.createElement」の第1引数にコンポーネントを渡します。ここでは「HelloClass」を渡すことで「HelloClass」のエレメントを生成しています。このエレメントを描画すると、「HelloClass」の「render」の中で戻り値として返しているエレメントが描画されます。

属性

 Reactでは、コンポーネントはできる限り抽象的に書くことが一般的です。依存性のある値は「属性」を使って、外部から注入する形をとります。

ソースコードを次のコードに書き換えてください。

// コンポーネントの定義
var HelloClass = React.createClass({
    render: function() {
        return React.createElement(
            "div", null, "Hello, ", this.props.name
        );
    }
});
// エレメントの生成
var helloElement = React.createElement(
	HelloClass, { name: "Taro" }
);
// 描画
ReactDOM.render(helloElement, content);

 「helloElement」に代入しようとしている「React.createElement」の第2引数には、「{ name: "Taro" }」というオブジェクトを渡しています。これが属性のオブジェクトです。こうして渡したオブジェクトを、コンポーネント内から「props」で参照できます。

属性を持つコンポーネントの動作確認

状態

 コンポーネントは、自分自身の「状態」を保持することができます。状態は「state」に保持され「setState」によって変更できます。また「state」が変更されたときには「render」が呼び出され、自動的に再描画されます。

 次のコードでは、1秒ごとに状態が変わるようなコンポーネントを定義しています。

var Ticker = React.createClass({
	// 初期状態を定義
	getInitialState: function() {
		return {times: 0};
	},
	// コンポーネントがDOMツリーに追加されたときに呼ばれる
	componentDidMount: function() {
		this.interval = setInterval(this.tick, 1000);
	},
	// コンポーネントがDOMツリーから削除されるときに呼ばれる
	componentWillUnmount: function() {
		clearInterval(this.interval);
	},
	// 状態が変更されたら呼ばれる
	render: function() {
		return React.createElement(
			"div", null, "Times: ", this.state.times
		);
	},
	tick: function() {
	this.setState({times: this.state.times + 1});
	}
});
var helloElement = React.createElement(Ticker);
ReactDOM.render(helloElement, content);

 「state」の初期値は「getInitialState」で定義します。戻り値として返すオブジェクトが初期値になります。ここでは初期値が「0」となる「times」を持つオブジェクトを返しています。

 「componentDidMount」「componentWillUnmount」はコンポーネントのライフサイクルメソッドです。「componentDidMount」はコンポーネントがDOMツリーに追加されたときに呼ばれます。この中では「setInterval」を呼び出しており、1秒おきに「tick」を呼び出すようにしています。また「componentWillUnmount」はコンポーネントがDOMツリーから削除されるときに呼び出されます。このメソッドの中では「clearInterval」を呼び出すことで、1秒おきの呼び出しをキャンセルしています。

 「tick」は1秒おきに呼び出されます。この中ではコンポーネントの状態を変更するために「setState」を呼び出しています。

 ブラウザで開くと、1秒おきに表示が切り替わっていることが確認できます。1秒ごとに「setState」によって変更され、その変更によって「render」が呼び出されています。

タイマーの動作確認
       1|2|3 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。