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
まだ使わないけど後々POSTをサーバサイドで処理することになるからサーバを用意してね。でもサーバーサイドに興味ないなら、ソースを用意してあるから、それ使ってね。みたいなことが書いてました。
追記:最後まで読んで気づきましたがサーバサイドやらないようです。どうもやりたければ自分でやっていいし、そうじゃない人はソースつかってどうぞ的な意味合いだったようです・・・
#Getting started
前回との違い、ないしは要点:
- スタータキットを使わずCDN上のライブラリを使う
- ファイルを分けずpublic/index.htmlのscriptタグ内に記述
- jQueryを使用するがReactで必須ではない
#Your first component
Reactは全てコンポーネントでコンポーネントが階層構造をとるそうです。今回の構成は以下のようになります。
- CommentBox
- ┗ CommentList
- ┗ Comment
- ┗ CommentForm
まずCommentBoxを作るようです。
<!-- 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コンポーネントツリーを返す
- コンポーネントツリーは描画に使われる
-
タグは実際にはDOMオブジェクトではなく、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
からアクセスできます。JSX中では{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をエスケープせずに表示するための手段ですがXSSの危険性があります。十分に信頼できる場合以外使用するなと本文にあります。気を付けて使いましょう。長くなってきたので一端切ります。まだスクロールバー的に半分くらいです。