いまさら聞けないReact、Virtual DOM、JSX超入門(2/3 ページ)

» 2016年07月28日 05時00分 公開
[諏訪悠紀クラスメソッド]

JSXとBabelの使い方

 エレメントを生成するコードは「JSX」を使うと、よりシンプルに記述できます。JSXはECMAScript(JavaScript)にXMLライクのシンタックスを追加する言語拡張です。JSXを使うと、JavaScriptコード中にHTMLタグを埋め込んでいるかのように記述できます。

 Webページ内でJSXを使用するには、「Babel」を導入する方法が最も簡単です。Babelは、ECMAScript(JavaScript)の次期バージョンを現行のブラウザ上で実行可能な形式に変換する機能を持つ、JavaScriptコンパイラです。BabelはJSXシンタックスを変換する機能を持っているため、Babelを導入することでJSXシンタックスを使用できます。

 通常ではnpmでインストールしてbrowserifyやwebpackを使って変換を行いますが、「babel-standalone」をWebページに組み込むと、ブラウザ単独で変換できます。デバッグ環境での使用に適しているため、本稿では、この方法を使います(パフォーマンスの面から、実際に公開するWebアプリでは使用しない方がよいとされています)。

 「コンポーネントの定義」で記述したコードを、JSXを使ったコードに書き換えてみましょう。

<!-- 追加する -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.10.3/babel.min.js"></script>
 
<!-- text/javascript を text/babel に変更する -->
<script type="text/babel">
// コンポーネントの定義
var HelloClass = React.createClass({
	render: function() {
		return <div>Hello, {this.props.name}</div>;
	}
});
// エレメントの生成
var helloElement = <HelloClass name="Taro" />;
// 描画
ReactDOM.render(helloElement, content);
</script>

 「helloElement」を生成するコードが大きく変わっています。JSXを使うと「React.createElement」メソッドを直接呼ばすに、HTMLタグと同じような形式で記述できます。なお、JSXシンタックスコード内でJavaScriptコードを記述する場合は「{}」で囲うようにします。

 以降、本稿ではJSXを用いたコードで記述します。

Reactと他のライブラリを組み合わせる方法

 Reactは他のライブラリと共存させやすい、柔軟なインタフェースを提供しています。そのため、他のライブラリと容易に組み合わせることができます。

 ここでは、Markdown形式の文字列をHTML形式の文字列に変換するライブラリ「marked」を組み合わせて、簡単なMarkdownエディタを作ってみましょう。

 まずはmarkedをCDNから参照します。次の「script」タグを追加してください。

<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.js"></script>
var Editor = React.createClass({
	getInitialState: function() {
		return {value: "**Markdown** を記述できます"};
	},
	handleChange: function(e) {
		this.setState({value: e.target.value});
	},
	markup: function() {
		return { __html: marked(this.state.value) };
	},
	render: function() {
		return <div>
                 <h3>Input</h3>
                 <textarea
                   onChange={this.handleChange}
                   defaultValue={this.state.value} />
                 <h3>Output</h3>
                 <div dangerouslySetInnerHTML={this.markup()} />
               </div>;
	}
});
ReactDOM.render(<Editor />, content);

 「render」では、入力に当たる「textarea」と出力先である「div」を描画しています。「render」では単一のエレメントを返さなければならないため、複数のエレメントを返す必要がある場合は「div」でまとめるようにします。

 「handleChange」は「textarea」の値が変更されたときに呼び出されます。「setState」を呼び出すことで、状態を変更しています。ここでのポイントは「handleChange」の引数として渡されるイベントのオブジェクトです。「target」でイベントを発火した対象のエレメント自体を参照できます。ここでは「target」が「textarea」となるので、「value」を参照することで入力された文字列を取得しています。

 状態が変更されると再度「render」が呼び出されます。出力先の「div」では、「dangerouslySetInnerHTML」を使ってHTMLを埋め込んでいます。「dangerouslySetInnerHTML」に「__html」を持つオブジェクトを渡すことで、「__html」の値がHTMLテキストとして扱われ、実際に描画されます。ここでは、「marked」ライブラリで提供されている変換のための関数である「marked」を呼び出しています。

Markdownエディタの動作確認

コラム「Facebookが提唱するアプリの設計手法Fluxとは」

 「Flux」とは、Facebookが提唱しているアプリケーションの設計手法の1つです。「データの流れを一方向にする」という原則を作り、幾つかの種類のコンポーネントの組み合わせによって実現します。

 Fluxは、例えば次のようなフローで処理を行います。

  1. Viewのイベントが発生したときに、Actionを生成する
  2. Actionが生成されたときに、ActionはDispatcherに知らせる
  3. Dispatcherは、登録されているStoreのコールバックを呼び出す
  4. Storeはコールバックが呼ばれたとき、Storeは自身の状態を変更する
  5. ViewはStoreの状態の変更に応じて、Viewを再描画する
Fluxのデータフロー(https://github.com/facebook/fluxより転載)

 本記事では詳細な解説は行いません。アーキテクチャについてより詳しく知りたい方は、次のドキュメントを参考にしてください。

 ReactはFluxのView部分を担当することができるフレームワークです。WebアプリケーションのフロントエンドにReactを使う場合は、Fluxの採用も考えましょう。


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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