React.jsのTutorialを試してみる（１

http://facebook.github.io/react/docs/tutorial.html
React.jsのTutorialを試していきます。長くなったので何部かに分けます。間違いあったら指摘頂けると助かります。

#Tutorial
ブログに使用できるコメントボックスを簡単につくろう！みたいな内容のようです。
目標は

* コメントビュー
* コメント送信フォーム
* バックエンド処理用のフック付

です。また

* Optimistic commenting: 体感速度を上げるためにサーバ送信前にコメントをリストに表示する。
* Live updates: 他のユーザがコメントしたらリアルタイムに表示する
* Markdown formatting: マークアップ

をサポートするようです。

#Want to skip all this and just see the source?
ソースは https://github.com/reactjs/react-tutorial にあるそうです。

#Running a server
まだ使わないけど後々ＰＯＳＴをサーバサイドで処理することになるからサーバを用意してね。でもサーバーサイドに興味ないなら、ソースを用意してあるから、それ使ってね。みたいなことが書いてました。
追記：最後まで読んで気づきましたがサーバサイドやらないようです。どうもやりたければ自分でやっていいし、そうじゃない人はソースつかってどうぞ的な意味合いだったようです・・・

#Getting started
前回との違い、ないしは要点：

* スタータキットを使わずＣＤＮ上のライブラリを使う
* ファイルを分けずpublic/index.htmlのscriptタグ内に記述
* jQueryを使用するがReactで必須ではない

#Your first component
 Reactは全てコンポーネントでコンポーネントが階層構造をとるそうです。今回の構成は以下のようになります。

* CommentBox
*  ┗ CommentList
*  　┗ Comment
*  ┗ CommentForm

まずCommentBoxを作るようです。

``` public/index.html
<!-- index.html -->
<html>
  <head>
    <title>Hello React</title>
    <script src="https://fb.me/react-0.13.1.js"></script>
    <script src="https://fb.me/JSXTransformer-0.13.1.js"></script>
    <script src="https://code.jquery.com/jquery-1.10.0.min.js"></script>
  </head>
  <body>
    <div id="content"></div>
    <script type="text/jsx">
      var CommentBox = React.createClass({
        render: function() {
          return (
            <div className="commentBox">
              Hello, world! I am a CommentBox.
            </div>
          );
        }
      });
      React.render(
        <CommentBox />,
        document.getElementById('content')
      );
    </script>
  </body>
</html>
```

``` ブラウザ画面.
Hello, world! I am a CommentBox.
```
できましたね。

##JSX Syntax 
JSXの説明。javascript中のdivタグがReact.createElementのシュガーシンタックスであるとのこと。

##What's going on
要約：

* React.createClassはReactオブジェクトを作る
* ReactオブジェクトにはメソッドがcreateClassで渡される
* renderメソッドはReactコンポーネントツリーを返す
* コンポーネントツリーは描画に使われる
* <div>タグは実際にはＤＯＭオブジェクトではなく、React div componentのインスタンスである
* デフォルトではHTML文字列を扱わないため、Reactは安全である

##Composing components
つぎにCommentListとCommentFormのスケルトンを定義し、CommentBoxのコンポーネントツリーに追加します。スケルトンはCommentBoxの前に記述してください。

``` public/index.html
<!-- index.html -->
<html>
  <head>
    <title>Hello React</title>
    <script src="https://fb.me/react-0.13.1.js"></script>
    <script src="https://fb.me/JSXTransformer-0.13.1.js"></script>
    <script src="https://code.jquery.com/jquery-1.10.0.min.js"></script>
  </head>
  <body>
    <div id="content"></div>
    <script type="text/jsx">
      
      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>
          );
        }
      });
      
      var CommentBox = React.createClass({
        render: function() {
          return (
            <div className="commentBox">
              <h1>Comments</h1>
              <CommentList />
              <CommentForm />
            </div>
          );
        }
      });
      
      React.render(
        <CommentBox />,
        document.getElementById('content')
      );
    </script>
  </body>
</html>
```

``` ブラウザ画面.
Comments

Hello, world! I am a CommentList.
Hello, world! I am a CommentForm.
```
できましたね。

##Using props
次はCommentコンポーネントです。データは親コンポーネントから渡されます。そのデータは子の`this.props`からアクセスできます。ＪＳＸ中では`{this.props.author}`のように記述します。またネストした子には`{this.props.children}`でアクセスできます。

##Component Properties
ではCommentを定義し、それに対しCommentListからauthorと本文を渡します。
まずCommentコンポーネントを先頭に定義します。

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

つぎにCommentListからCommentにデータを渡します。

``` public/index.html(1部分)
      var CommentList = React.createClass({
        render: function() {
          return (
            <div className="commentList">
              <Comment author="Pete Hunt">This is one comment</Comment>
              <Comment author="Jordan Walke">This is *another* comment</Comment>
            </div>
          );
        }
      });
```

``` ブラウザ画面.
Comments

Pete Hunt

This is one comment
Jordan Walke

This is *another* comment
Hello, world! I am a CommentForm.
```
できましたね。なおCommentの`{this.props.children}`はテキストノードを指しています。

##Adding Markdown
マークダウンですがライブラリを使用するようです。
headに以下を追加します。

```
    <script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/0.3.1/showdown.min.js"></script>
```
そしてCommentを次のように変更します。

```
      var converter = new Showdown.converter();
      var Comment = React.createClass({
        render: function() {
          var rawMarkup = converter.makeHtml(this.props.children.toString());
          return (
            <div className="comment">
              <h2 className="commentAuthor">
                {this.props.author}
              </h2>
              <span dangerouslySetInnerHTML={{__html: rawMarkup}} />
            </div>
          );
        }
      });
```
ここで重要なのが`dangerouslySetInnerHTML`です。これはHTMLをエスケープせずに表示するための手段ですがＸＳＳの危険性があります。十分に信頼できる場合以外使用するなと本文にあります。気を付けて使いましょう。

長くなってきたので一端切ります。まだスクロールバー的に半分くらいです。

[次回](http://qiita.com/kazusa-qooq/items/61ee2b29d1bcc241bbe4)