Reactチュートリアル入門:クライアントサイド編

チュートリアル | React(何故か2016-10-23時点ではNot Found) を理解しながら写経すると、Reactで簡単なWebアプリが作れるようになる。 しかし、僕自身もそうだが、テンプレートを使ったWebアプリしか作ったことしかなく、 Reactを理解したいという人向けに、今回はクライアントサイドだけをいじってWebアプリを作成する。 そもそもReactとは何か、Reactを使うと何が便利なのかを知りたい人は Reactを使うとなぜjQueryが要らなくなるのか が分りやすい。

Reactチュートリアルの始め方

Reactチュートリアルのプロジェクトをクローンして、パッケージをインストールする。

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

初期設定

プロジェクトの中身を見ると、色々ファイルが入っているので、必要なものだけに絞って残りは削除する。

react-tutorial
├── LICENSE
├── README.md
├── app.json
├── comments.json
├── db.py
├── db.pyc
├── node_modules
│   ├── body-parser
│   └── express
├── npm-debug.log
├── package.json
├── public
│   ├── css
│   ├── index.html
│   └── scripts
├── requirements.txt
├── server.go
├── server.js
├── server.php
├── server.pl
├── server.py
└── server.rb

 
以下が削除した結果。

react-tutorial
├── comments.json     // 今回は使わない
├── node_modules      // npm installで生成されたフォルダー
│   ├── body-parser
│   └── express
├── package.json      // メタ情報ファイル
├── public
│   ├── css
│   ├── index.html    // 今回編集する唯一のファイル
│   └── scripts
├── requirements.txt  // 後で使う
├── server.js         // 後で実行する
└── server.py         // 後で実行する
  • comments.json
    • コメントが書かれたJSONファイル。今回は使わない。
  • node_modules
    • "npm install"を実行した時に生成されたフォルダー。Reactなど今回使うnode.js関連のパッケージが入っている。基本触らない。
  • package.json
    • ライセンスや著者、バージョンなど記述されたメタ情報ファイル。"npm install"の後でパッケージの依存関係の記述も自動的に追加されている。
  • public
    • HTML・CSSJavaScript・画像など、クライアントサイドのファイルを置く場所。
  • index.html
    • 今回は編集する唯一のファイル。
  • server.jsとserver.py
    • アプリケーション・サーバーを起動するNode.jsとPythonのコード。他の言語を使いたい人は、それらのファイルを残す。
  • requirements.txt
    • Pythonのサーバーサイドを実行する際に必要なライブラリーをインストールするための設定ファイル。

index.htmlを開くと以下のようになるが、今回は下の方のscriptダグで囲まれたエリアにReactコードを追記していく。 そのため、"script/example.js"をインポートしているscriptタグをコメントアウトしておく。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>React Tutorial</title>
    <!-- Not present in the tutorial. Just for basic styling. -->
    <link rel="stylesheet" href="css/base.css" />
    <script src="https://unpkg.com/react@15.3.0/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15.3.0/dist/react-dom.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    <script src="https://unpkg.com/jquery@3.1.0/dist/jquery.min.js"></script>
    <script src="https://unpkg.com/remarkable@1.7.1/dist/remarkable.min.js"></script>
  </head>
  <body>
    <div id="content"></div>
    <!--
    <script type="text/babel" src="scripts/example.js"></script>
    -->
    <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>

Reactの実装

最終的なWebアプリの見た目はこんな感じ。

f:id:Shoto:20161023190302p:plain

 
まずは、Webアプリで表示するためのJSONを記述する。

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

 
ここからReact。 上記ので記述したdataを、CommentBoxに入れた結果を、index.htmlの<div id="content"></div>内にレンダリングする、 という意味のコードを記述する。 レンダリングするDOMの構造を、このCommentBoxから始まるReactによって作成することが、今回の主な内容であり、Reactのコアな部分になる。

      ReactDOM.render(
        <CommentBox data={data} />,
        document.getElementById('content')
      );

 
上記のdataキーは、CommentBoxでは{this.props.data}として表される。 逆に言えば、親のデータは{this.props.xxx}で取得できる。 また{this.props.data}は、子であるCommentListcommentsキーにそのまま渡される(オリジナルはdataキー)。 ここより下は、コメントのリストが表示されるので、h1タグでCommentsと記述しておく。

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

 
上記のcommentsキーは、CommentListでは{this.props.comments}となる。 これはJSONのobjectのarrayなので、個々のobjectを子であるCommentに渡すために、 map関数を使っている。またCommentへはobjectの値をセットしている。

      var CommentList = React.createClass({
        render: function() {
          var commentNodes = this.props.comments.map(function (comment) {
            return (
              <Comment author={comment.author} key={comment.id}>
                {comment.text}
              </Comment>
            );
          });
          return (
            <div className="commentList">
              {commentNodes}
            </div>
          );
        }
      });

 
上記のauthorキーは{this.props.author}になる。 また上記の{comment.text}{this.props.children}になる。

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

 
このようにReactによって、CommetBox以下でDOMの構造が構築された後、最終的にレンダリングされる。 index.htmlに追記したコードをまとめると以下のようになる。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>React Tutorial</title>
    <!-- Not present in the tutorial. Just for basic styling. -->
    <link rel="stylesheet" href="css/base.css" />
    <script src="https://unpkg.com/react@15.3.0/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15.3.0/dist/react-dom.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    <script src="https://unpkg.com/jquery@3.1.0/dist/jquery.min.js"></script>
    <script src="https://unpkg.com/remarkable@1.7.1/dist/remarkable.min.js"></script>
  </head>
  <body>
    <div id="content"></div>
    <!--
    <script type="text/babel" src="scripts/example.js"></script>
    -->
    <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.
      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 comments={this.props.data} />
            </div>
          );
        }
      });

      var CommentList = React.createClass({
        render: function() {
          var commentNodes = this.comments.data.map(function (comment) {
            return (
              <Comment author={comment.author} key={comment.id}>
                {comment.text}
              </Comment>
            );
          });
          return (
            <div className="commentList">
              {commentNodes}
            </div>
          );
        }
      });

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

      ReactDOM.render(
        <CommentBox data={data} />,
        document.getElementById('content')
      );
    </script>
  </body>
</html>

アプリケーション・サーバーの実行

以下のいずれかを実行し、http://localhost:3000/にアクセスすれば、 2つのコメントがレンダリングされた画面が表示されるはず。

  • Node.js
node server.js
pip install -r requirements.txt
python server.py

pipの実行は初回だけでよい。

参考文献