Help us understand the problem. What is going on with this article?

React.jsチュートリアルをやる(1)

More than 3 years have passed since last update.

公式

公式のチュートリアルは日本語のページもあったけど、自分には少し読みにくかったので英語の方でやった。
ja : https://facebook.github.io/react/docs/tutorial-ja-JP.html
en : https://facebook.github.io/react/docs/tutorial.html

準備

まずはチュートリアル用のリポジトリを公式からcloneしてパッケージをインストールする。
ここにReactから接続するための簡易サーバが用意されているので、ありがたく使わせてもらう。

$ git clone https://github.com/reactjs/react-tutorial.git
$ cd react-tutorial
$ npm install

自分で書いたコードを実行させたいので、
/public/index.htmlを開いて下記のように書き換える。

index.html
<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>React Tutorial</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.min.js"></script>
  </head>
  <body>
    <div id="content"></div>
    <script type="text/babel">
      // To get started with this tutorial running your own code, simply remove
      // the script tag loading scripts/example.js and start writing code here.
    </script>
  </body>
</html>

今回は<script type="text/babel"></script>の中にreactのコードを書いていく。

コンポーネント

Reactはコンポーネント単位で処理を記述していく。
今回作るコメント投稿フォームは下記のようなコンポーネント構造をとる。

- CommentBox
  - CommentList
    - Comment
  - CommentForm

まずはCommentBoxのコンポーネントを作ってみる。

var CommentBox = React.createClass({
  render: function() {
    return (
      <div className="commentBox">
        Hello, world! I am a CommentBox.
      </div>
    );
  }
});
ReactDOM.render(
  <CommentBox />,
  document.getElementById('content')
);

HTMLのエレメントはローワーキャメルケース、Reactクラスはアッパーキャメルケースで書く。

DOMっぽいシンタックスシュガー

また、

return (
  <div className="commentBox">
    Hello, world! I am a CommentBox.
  </div>
);

はJSXのシンタックスシュガーで、DOMをそのままjsコードの中に記述できるようになっている。ただこれをそのまま実行するとjsの実行エラーになるので、実行する前にコンパイルする必要がある。
コンパイルしてくれるのは先ほどのindex.htmlの中に記述した
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>

先ほどのコードがコンパイルされると

return (
  React.createElement('div', {className: "commentBox"},
  "Hello, world! I am a CommentBox."
  )
);

のようになり、jsコードとして正常に実行される。

そもそも何をしているのか

React.createClass関数でコンポーネントを生成して、その引数として渡しているオブジェクトのrender関数の中でDOMを定義している。で、ここで定義されたDOMがコンポーネントとして利用される。ここで定義するDOMはあくまでReactのdivインスタンスで、実際のDOMとは違う。最終的にDOMに変換されるReactのdivインスタンス。

ReactDOM.renderは、フレームワークの起動とルートコンポーネント(ここではCommentBox)のインスタンス化を行っている。

コンポーネントを組み合わせる

CommentListコンポーネントとCommentFormコンポーネントを作ってCommentBoxと組み合わせる。

CommentListCommentFormの追加

var CommentList = React.createClass({
  render: function() {
    return (
      <div className="commentList">
        Hello, world! I am a CommentList.
      </div>
    );
  }
});

var CommentForm = React.createClass({
  render: function() {
    return (
      <div className="commentForm">
        Hello, world! I am a CommentForm.
      </div>
    );
  }
});

CommentBoxのアップデート

var CommentBox = React.createClass({
  render: function() {
    return (
      <div className="commentBox">
-       Hello, world! I am a CommentBox.
+       <h1>Comments</h1>
+       <CommentList />
+       <CommentForm />
      </div>
    );
  }
});

このように書くことで、DOMを構造化できる。

props(property)を使う

Reactでは、子コンポーネントから親コンポーネントのデータをプロパティとして受け継ぐことができる。プロパティは子コンポーネントの中でthis.propsを通して取得する。
ここではCommentコンポーネントを新しく作り、CommentListから渡ってくるデータを受け取っている。

var Comment = React.createClass({
  render: function() {
    return (
      <div className="comment">
        <h2 className="commentAuthor">
          {this.props.author}
        </h2>
        {this.props.children}
      </div>
    );
  }
});

DOMツリー(JSX)の中で{this.props.children}のように書くことでテキストやコンポーネントを差し込むことができる。

次に親コンポーネントから子コンポーネントへデータを渡す。

var data = [
  {id: 1, author: "Pete Hunt", text: "This is one comment"},
  {id: 2, author: "Jordan Walke", text: "This is *another* comment"}
];

var CommentBox = React.createClass({
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
-       <CommentList />
+       <CommentList data={this.props.data} />
        <CommentForm />
      </div>
    );
  }
});

ReactDOM.render(
- <CommentBox />,
+ <CommentBox data={data} />,
  document.getElementById('content')
);
var CommentList = React.createClass({
  render: function() {
    var commentNodes = this.props.data.map(function(comment) {
      return (
-       <div className="commentList">
-         Hello, world! I am a CommentList.
-       </div>
+       <Comment author={comment.author} key={comment.id}>
+         {comment.text}
+       </Comment>
      );
    });
    return (
      <div className="commentList">
        {commentNodes}
      </div>
    );
  }
});

これでデータの受け渡しができた。

(1)はここまで。React.jsチュートリアルをやる(2) へ続く。

saekis
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away