インタラクティブと動的UI

Reactを使用したデータの表示については、既に学んでいることでしょう。 ここでは、インタラクティブなUIの作り方について見て行きましょう。

シンプルな例

var LikeButton = React.createClass({
  getInitialState: function() {
    return {liked: false};
  },
  handleClick: function(event) {
    this.setState({liked: !this.state.liked});
  },
  render: function() {
    var text = this.state.liked ? 'like' : 'haven't liked';
    return (
      <p onClick={this.handleClick}>
        You {text} this. Click to toggle.
      </p>
    );
  }
});

React.render(
  <LikeButton />,
  document.getElementById('example')
);

イベント・ハンドリングと人工的なイベント

通常のHTMLで行う事と似た方法で、Reactでもキャメルケースのプロパティをイベントハンドラに渡すことが出来ます。 Reactは人工的なイベントシステムを実装することで、IE8とそれ以降で同じように全てのイベントが動作する事を保証してくれます。 つまり、Reactは仕様に沿ったイベントのバブルとキャプチャ方法を把握し、 あなたのイベントハンドラに渡されるイベントが、使用されているブラウザに関係なく、 W3Cの仕様と一致する事を保証してくれます。

もし、スマートフォンやタブレットのようなタッチデバイス上でReactを使用したい場合は、 React.initializeTouchEvents(true);を呼び出し、タッチ・イベントハンドリングを有効にして下さい。

内部構造: 自動バインディングとイベント委譲

React内部では、コードのパフォーマンスの向上と理解し易さを維持するために、幾つかの事を行っています。

自動バインディング:
JavaScriptでコールバックが作成される際に、通常はthisの値が正しくなるように、 そのインスタンにメソッドを明示的にバインドする必要があります。 Reactでは、各メソッドは自動的にそのコンポーネントのインスタンスにバインドされます。 ReactはCPUとメモリを極めて効率的に扱うために、それらのバインドされたメソッドをキャッシュします。 また、これはタイピングを減らすことにも繋がります。
イベントの委譲:
Reactは、実際にはそのノード自身に対してイベントハンドラを割り当てる、ということはしません。 Reactは開始された際に、単一のイベントを使用して、トップ階層で全てのイベントのリスニングを始めます。 コンポーネントのマウント時またはアンマウント時に、イベントハンドラは単純に内部マッピングに対して追加または削除されます。 イベント発生時、Reactはこのマッピングを使用することでイベントの送り先の情報を取得します。 イベントハンドラがマッピング内に存在しない場合は、Reactのイベントハンドラは何も行いません。 何故これが速いのかの詳細については、David Walsh氏の素晴らしいブログの記事を参照して下さい。

コンポーネントはstateのマシーン

Reactは単なるstateのマシーンであると考えることが出来ます。 UIが様々なstateであり、それらのstateを描画するものであると考えると、 UIの一貫性を保つことが容易になります。

Reactでは、単純にコンポーネントのstateを更新すると、その新しいstateを基に新しいUIが描画されます。 Reactは、最も効率的な方法であなたのDOM更新の面倒を見てくれます。

Stateはどのように動作するか

データが変更されたことをReactに伝える共通の方法は、setState(data, callback)を呼び出すことです。 このメソッドはthis.stateにデータをマージして再描画を行うメソッドです。 コンポーネントの再描画が完了すると、任意のコールバックが呼び出されます。 ReactがUIを最新に保つための面倒を見てくれるため、ほとんどのケースでコールバックの提供は不要になるでしょう。

どのコンポーネントがStateを持つべき?

コンポーネントの多くは単にpropsからデータを取得し、それを描画するだけにするべきです。 ただし、時にはユーザーからの入力、サーバーのリクエスト、時間の経過などを受け付ける必要があるでしょう。 このような場合には、stateを使用します。

出来るだけ多くのコンポーネントをステートレスにすることを心がけて下さい。 これを行うことで、そのstateをロジックの重要部分へ隔離して冗長性を最小限にし、 アプリケーションを理解し易いものにします。

一般的なパターンは幾つかのデータを描画するだけのステートレスなコンポーネントを作成し、 それらの階層の上にpropsを通して階層の下の子にそのstateを渡すステートフルなコンポーネントを持つことです。 ステートフルなコンポーネントは全てのインタラクションなロジックをカプセル化する一方、 ステートレスなコンポーネントは宣言的な方法でデータの描画の面倒を見ます。

何をStateにするべきか?

stateには、UI更新のトリガに繋がる、コンポーネントのイベントハンドラが変更するかもしれないデータを含めるべきです。 実際のアプリケーションでは、このデータはとても小さくJSONにシリアライズ可能なものになる傾向があります。 ステートフルなコンポーネントを構築する際は、そのstateは可能な限り最小なものになるように考え、 それらのプロパティをthis.stateに格納するだけにします。 render()の内部は、このstateを基にする事を必要とする、その他の情報の単純な計算をするだけにします。 あなたは、この方法によるアプリケーション構築こそが、最上のアプリケーション構築に繋がると気づくでしょう。 何故なら、冗長な値または計算値をstateに追加することに対して、それをReactに処理させるのでは無く、 それらを同期して明確にする必要があると気づかせてくれるからです。(翻訳に自信なし)

何をStateにするべきではないか?

this.stateは、UIのステート(状態)を表す必要がある最小量のデータのみを含めるべきです。 そのため、次のようなものを含めるべきではありません。

計算データ :
stateに基いて値を事前に処理するような事はしないで下さい。 render()内で全ての処理を行うことで、UIを一定に保つことが容易になります。 例えば、stateの項目リストの配列を持っていて、そのカウント数を文字列として描画したい場合は、 stateを文字列にするのでは無く、単純にrender()メソッド内でthis.state.listItems.length + ' list items'として描画します。
Reactコンポーネント :
propsとstateが基になる情報については、render()内でビルドして下さい。
propsと重複するデータ
可能であれば、情報源となるpropsを使用することを検討して下さい。 stateにpropsを格納する正当な使用例を1つ挙げるとすると、propsはいずれ変更されてしまう可能性があることから、 その値の直前(previous)の値を知るために使用することでしょう。

 Back to top

© 2013-2017 Facebook Inc.
Documentation licensed under CC BY 4.0.

このページは、ページトップのリンク先のReact内のページを翻訳した内容を基に構成されています。 下記の項目を確認し、必要に応じて公式のドキュメントをご確認ください。 もし、誤訳などの間違いを見つけましたら、 @tomofまで教えていただければ幸いです。

  • ドキュメントの情報が古い可能性があります。
  • "訳注:"などの断わりを入れた上で、日本人向けの情報やより分かり易くするための追記を行っている事があります。