Reactjsのチュートリアルを試す
Reactjsって?
javascriptの仮想DOMを使用しているフレームワーク
angularjsとかのディレクティブみたいなもん
jsxとかいう言語形態で使っているけどjsに変換は可能、またchromeで動かすこともできる
チュートリアル
sample1
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Sample1</title> <script src="js/react.js"></script> <script src="js/JSXTransformer.js"></script> <script src="js/jquery-2.1.4.min.js"></script> </head> <body> <div id="content"></div> <script type="text/jsx"> /** * CommentBoxというコンポーネントを作成 * React.createClassで作成する */ 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>
仮想DOMの貼り方
とっても簡単です(^_^;)
sample2
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Sample2</title> <script src="js/react.js"></script> <script src="js/JSXTransformer.js"></script> <script src="js/jquery-2.1.4.min.js"></script> </head> <body> <div id="content"></div> <script type="text/jsx"> /** * CommentBoxというコンポーネントの中に * CommentList、CommentFormのコンポーネントを配置してコンポーネントを連鎖的に生成 */ var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList /> <CommentForm /> </div> ); } }); 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> ); } }); React.render( <CommentBox />, document.getElementById('content') ); </script> </body> </html>
sample3
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Sample3</title> <script src="js/react.js"></script> <script src="js/JSXTransformer.js"></script> <script src="js/jquery-2.1.4.min.js"></script> </head> <body> <div id="content"></div> <script type="text/jsx"> /** * CommentListというコンポーネントの中に * Commentコンポーネントを用意、 authorなどの属性を用意して * Commentコンポーネントの中で使用する */ var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList /> <CommentForm /> </div> ); } }); 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> ); } }); var CommentForm = React.createClass({ render: function() { return ( <div className="commentForm"> Hello, world! I am a CommentForm. </div> ); } }); var Comment = React.createClass({ render: function() { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> {this.props.children} </div> ); } }); React.render( <CommentBox />, document.getElementById('content') ); </script> </body> </html>
属性や子要素の値を設定できます
sample4
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Sample4</title> <script src="js/react.js"></script> <script src="js/JSXTransformer.js"></script> <script src="js/jquery-2.1.4.min.js"></script> <script src="js/marked.min.js"></script> </head> <body> <div id="content"></div> <script type="text/jsx"> /** * Commentコンポーネントの中で使用する文字列をマークダウン化する * しかし、通常の方法ではエスケープするのでhtmlに変換する * ※リスクが高いので気をつける必要があります */ var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList /> <CommentForm /> </div> ); } }); 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> ); } }); var CommentForm = React.createClass({ render: function() { return ( <div className="commentForm"> Hello, world! I am a CommentForm. </div> ); } }); var Comment = React.createClass({ render: function() { // マークダウンしたhtmlを格納 var rawMarkup = marked(this.props.children.toString(), {sanitize: true}); return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> <!-- htmlの形式のまま表示 --> <span dangerouslySetInnerHTML={{__html: rawMarkup}} /> </div> ); } }); React.render( <CommentBox />, document.getElementById('content') ); </script> </body> </html>
HTMLをそのまま表示したい場合はXSSに気をつける必要があるので気をつけてね
sample5
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Sample5</title> <script src="js/react.js"></script> <script src="js/JSXTransformer.js"></script> <script src="js/jquery-2.1.4.min.js"></script> <script src="js/marked.min.js"></script> </head> <body> <div id="content"></div> <script type="text/jsx"> /** * 静的に定義されたデータをコンポーネントにバインドして表示 */ var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.props.data} /> <CommentForm /> </div> ); } }); var CommentList = React.createClass({ render: function() { // this.props.dataをmap処理で定義 var commentNodes = this.props.data.map(function (comment) { return ( <Comment author={comment.author}> {comment.text} </Comment> ); }); return ( <div className="commentList"> {commentNodes} </div> ); } }); var CommentForm = React.createClass({ render: function() { return ( <div className="commentForm"> Hello, world! I am a CommentForm. </div> ); } }); var Comment = React.createClass({ render: function() { // マークダウンしたhtmlを格納 var rawMarkup = marked(this.props.children.toString(), {sanitize: true}); return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> <span dangerouslySetInnerHTML={{__html: rawMarkup}} /> </div> ); } }); // バインドするデータを準備 var data = [ {author: "Pete Hunt", text: "This is one comment"}, {author: "Jordan Walke", text: "This is *another* comment"} ]; React.render( // データを割り当て <CommentBox data={data} />, document.getElementById('content') ); </script> </body> </html>
単方向バインディングができます。
sample6
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Sample6</title> <script src="js/react.js"></script> <script src="js/JSXTransformer.js"></script> <script src="js/jquery-2.1.4.min.js"></script> <script src="js/marked.min.js"></script> </head> <body> <div id="content"></div> <script type="text/jsx"> /** * 静的に定義されたデータをコンポーネントにバインドして表示 */ var CommentBox = React.createClass({ // データ読み込み処理 loadCommentsFromServer: function() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, // 初期 getInitialState: function() { return {data: []}; }, // コンポーネントがレンダリングされた場合に呼ばれる componentDidMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, // 描画 render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm /> </div> ); } }); var CommentList = React.createClass({ render: function() { // this.props.dataをmap処理で定義 var commentNodes = this.props.data.map(function (comment) { return ( <Comment author={comment.author}> {comment.text} </Comment> ); }); return ( <div className="commentList"> {commentNodes} </div> ); } }); var CommentForm = React.createClass({ render: function() { return ( <div className="commentForm"> Hello, world! I am a CommentForm. </div> ); } }); var Comment = React.createClass({ render: function() { // マークダウンしたhtmlを格納 var rawMarkup = marked(this.props.children.toString(), {sanitize: true}); return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> <span dangerouslySetInnerHTML={{__html: rawMarkup}} /> </div> ); } }); // バインドするデータを準備 var data = [ {author: "Pete Hunt", text: "This is one comment"}, {author: "Jordan Walke", text: "This is *another* comment"} ]; React.render( // URLを割り当て(ajaxするためのファイル名を設定) <CommentBox url="comments.json" pollInterval={2000} />, document.getElementById('content') ); </script> </body> </html>
sample7
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Sample7</title> <script src="js/react.js"></script> <script src="js/JSXTransformer.js"></script> <script src="js/jquery-2.1.4.min.js"></script> <script src="js/marked.min.js"></script> </head> <body> <div id="content"></div> <script type="text/jsx"> /** * 静的に定義されたデータをコンポーネントにバインドして表示 */ var CommentBox = React.createClass({ // データ読み込み処理 loadCommentsFromServer: function() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, // 初期 getInitialState: function() { return {data: []}; }, // コンポーネントがレンダリングされた場合に呼ばれる componentDidMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, // submit handleCommentSubmit: function(comment) { var comments = this.state.data; var newComments = comments.concat([comment]); this.setState({data: newComments}); // post処理 $.ajax({ url: this.props.url, dataType: 'json', type: 'POST', data: comment, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, // 描画 render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm onCommentSubmit={this.handleCommentSubmit} /> </div> ); } }); var CommentList = React.createClass({ render: function() { // this.props.dataをmap処理で定義 var commentNodes = this.props.data.map(function (comment) { return ( <Comment author={comment.author}> {comment.text} </Comment> ); }); return ( <div className="commentList"> {commentNodes} </div> ); } }); var CommentForm = React.createClass({ handleSubmit: function(e) { // e.preventDefault(); // 値を取得してtrim var author = React.findDOMNode(this.refs.author).value.trim(); var text = React.findDOMNode(this.refs.text).value.trim(); if (!text || !author) { return; } // post処理 this.props.onCommentSubmit({author: author, text: text}); // クリア React.findDOMNode(this.refs.author).value = ''; React.findDOMNode(this.refs.text).value = ''; return; }, render: function() { return ( <form className="commentForm" onSubmit={this.handleSubmit}> <input type="text" placeholder="Your name" ref="author" /> <input type="text" placeholder="Say something..." ref="text" /> <input type="submit" value="Post" /> </form> ); } }); var Comment = React.createClass({ render: function() { // マークダウンしたhtmlを格納 var rawMarkup = marked(this.props.children.toString(), {sanitize: true}); return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> <span dangerouslySetInnerHTML={{__html: rawMarkup}} /> </div> ); } }); // バインドするデータを準備 var data = [ {author: "Pete Hunt", text: "This is one comment"}, {author: "Jordan Walke", text: "This is *another* comment"} ]; React.render( // URLを割り当て(ajaxするためのファイル名を設定) <CommentBox url="comments.json" pollInterval={2000} />, document.getElementById('content') ); </script> </body> </html>
サーバにpostする場合ことも可能、基本的にはReactJSの機能ではありません
イベントに応じて機能を使用できる