React

このエントリーをはてなブックマークに追加

このサイトについて

Reactの日本語リファレンスです。 Reactの本家サイト(英文) の内容を翻訳して作成していますが、誤訳や誤記があると思いますのでその点についてはご了承ください。 もし、誤訳などの間違いを見つけましたら、 @tomof まで教えていただければ幸いです。

JUST THE UI
人々の多くはReactをMVCのVとして使用します。 Reactは他の技術スタックについて想定を行わないため、 既存プロジェクトの小規模の機能でこれを試すことは簡単です。
VIRTUAL DOM
ReactはDOMを論理的に取り出し、シンプルなプログラミングモデルとより良いパフォーマンスを提供します。 また、ReactはNodeを使用するサーバー上でも描画可能であり、 React Nativeを使用したネイティブアプリも動かすことが可能です。
DATA FLOW
Reactは一方向のReactive(反応的?)なデータフローを実装することで、 ボイラープレート(定型的な表現)を減らし、 伝統的なデータバインディングと比較して、より簡単なものになります。

シンプルなコンポーネント

Reactコンポーネントは、入力データを取得し描画するものを返すrender()メソッドを実装します。 この例ではJSXと呼ばれるXMLライクな文法を使用しています。 コンポーネントに渡される入力データは、 render()によって、this.propsを介してアクセス可能になります。

JSXは任意であり、Reactを使用するために必須となるものではありません。 "Compiled JS"を参照して、JSXコンパイラによって生成される生のJavaScriptを確認してみてください。

管理人・訳者より:
これ以降のサンプルコードは、公式サイトではライブデモとライブコーディングを備えたサンプルになっていますので、 そちらを参照することをお勧めします。

// JSX
var HelloMessage = React.createClass({
  render: function() {
    return <div>Hello {this.props.name}</div>;
  }
});

React.render(<HelloMessage name="John" />, mountNode);
// Compiled JS
var HelloMessage = React.createClass({displayName: "HelloMessage",
  render: function() {
    return React.createElement("div", null, "Hello ", this.props.name);
  }
});

React.render(React.createElement(HelloMessage, {name: "John"}), mountNode);

ステートフルなコンポーネント

更に入力データ(this.propsを介してアクセスされた)を取得するために、 コンポーネントは内部の状態(ステート)データを保持することが出来ます。 コンポーネントの状態データが変更する際に、 描画されたマークアップはrender()が再実行される事によって更新されます。

// JSX
var Timer = React.createClass({
  getInitialState: function() {
    return {secondsElapsed: 0};
  },
  tick: function() {
    this.setState({secondsElapsed: this.state.secondsElapsed + 1});
  },
  componentDidMount: function() {
    this.interval = setInterval(this.tick, 1000);
  },
  componentWillUnmount: function() {
    clearInterval(this.interval);
  },
  render: function() {
    return (
      <div>Seconds Elapsed: {this.state.secondsElapsed}</div>
    );
  }
});

React.render(<Timer />, mountNode);
// Compiled JS
var Timer = React.createClass({displayName: "Timer",
  getInitialState: function() {
    return {secondsElapsed: 0};
  },
  tick: function() {
    this.setState({secondsElapsed: this.state.secondsElapsed + 1});
  },
  componentDidMount: function() {
    this.interval = setInterval(this.tick, 1000);
  },
  componentWillUnmount: function() {
    clearInterval(this.interval);
  },
  render: function() {
    return (
      React.createElement("div", null, "Seconds Elapsed: ", this.state.secondsElapsed)
    );
  }
});

React.render(React.createElement(Timer, null), mountNode);

アプリケーション

propsstateを使用することで、 小さなTodoアプリケーションを作ることが出来ます。 この例では、ユーザーに入力されたテキストだけで無く、 現在の項目のリストもstateを使用して追跡します。 イベントハンドラは、インライン描画されるように見えますが、 これらはイベントデリゲーションを使用して集められて実装されます。

// JSX
var TodoList = React.createClass({
  render: function() {
    var createItem = function(itemText, index) {
      return <li key={index + itemText}>{itemText}</li>;
    };
    return <ul>{this.props.items.map(createItem)}</ul>;
  }
});
var TodoApp = React.createClass({
  getInitialState: function() {
    return {items: [], text: ''};
  },
  onChange: function(e) {
    this.setState({text: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    var nextItems = this.state.items.concat([this.state.text]);
    var nextText = '';
    this.setState({items: nextItems, text: nextText});
  },
  render: function() {
    return (
      <div>
        <h3>TODO</h3>
        <TodoList items={this.state.items} />
        <form onSubmit={this.handleSubmit}>
          <input onChange={this.onChange} value={this.state.text} />
          <button>{'Add #' + (this.state.items.length + 1)}</button>
        </form>
      </div>
    );
  }
});

React.render(<TodoApp />, mountNode);
// Compiled JS
var TodoList = React.createClass({displayName: "TodoList",
  render: function() {
    var createItem = function(itemText, index) {
      return React.createElement("li", {key: index + itemText}, itemText);
    };
    return React.createElement("ul", null, this.props.items.map(createItem));
  }
});
var TodoApp = React.createClass({displayName: "TodoApp",
  getInitialState: function() {
    return {items: [], text: ''};
  },
  onChange: function(e) {
    this.setState({text: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    var nextItems = this.state.items.concat([this.state.text]);
    var nextText = '';
    this.setState({items: nextItems, text: nextText});
  },
  render: function() {
    return (
      React.createElement("div", null,
        React.createElement("h3", null, "TODO"),
        React.createElement(TodoList, {items: this.state.items}),
        React.createElement("form", {onSubmit: this.handleSubmit},
          React.createElement("input", {onChange: this.onChange, value: this.state.text}),
          React.createElement("button", null, 'Add #' + (this.state.items.length + 1))
        )
      )
    );
  }
});

React.render(React.createElement(TodoApp, null), mountNode);

外部プラグインを使用したコンポーネント

Reactは柔軟に他のライブラリとフレームワークと連結することが出来るフックを提供します。 この例では外部マークダウンライブラリであるShowdownを使用して、リアルタイムでテキストエリアの値を変換します。

// JSX
var converter = new Showdown.converter();

var MarkdownEditor = React.createClass({
  getInitialState: function() {
    return {value: 'Type some *markdown* here!'};
  },
  handleChange: function() {
    this.setState({value: React.findDOMNode(this.refs.textarea).value});
  },
  render: function() {
    return (
      <div className="MarkdownEditor">
        <h3>Input</h3>
        <textarea
          onChange={this.handleChange}
          ref="textarea"
          defaultValue={this.state.value} />
        <h3>Output</h3>
        <div
          className="content"
          dangerouslySetInnerHTML={{
            __html: converter.makeHtml(this.state.value)
          }}
        />
      </div>
    );
  }
});

React.render(<MarkdownEditor />, mountNode);
// Compiled JS
var converter = new Showdown.converter();

var MarkdownEditor = React.createClass({displayName: "MarkdownEditor",
  getInitialState: function() {
    return {value: 'Type some *markdown* here!'};
  },
  handleChange: function() {
    this.setState({value: React.findDOMNode(this.refs.textarea).value});
  },
  render: function() {
    return (
      React.createElement("div", {className: "MarkdownEditor"},
        React.createElement("h3", null, "Input"),
        React.createElement("textarea", {
          onChange: this.handleChange,
          ref: "textarea",
          defaultValue: this.state.value}),
        React.createElement("h3", null, "Output"),
        React.createElement("div", {
          className: "content",
          dangerouslySetInnerHTML: {
            __html: converter.makeHtml(this.state.value)
          }}
        )
      )
    );
  }
});

React.render(React.createElement(MarkdownEditor, null), mountNode);

 Back to top

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

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

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