あらすじ
React の勉強をかねて、Tutorialに書かれているソースをCoffeeScript化してみた。
チュートリアルページ
前準備
- coffee-react のインストール
- index.htmlの準備
- 共通JSの準備
# npm install -g coffee-react
index.html
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>React Starter kit</title>
<body>
<div id="content"></div>
<script src="node_modules/react/dist/react.js"></script>
<!-- <script src="node_modules/react/dist/JSXTransformer.js"></script> -->
<script src="//code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="node_modules/showdown/compressed/Showdown.min.js"></script>
<!--
<script src="node_modules/underscore/underscore-min.js"></script>
<script src="node_modules/backbone/backbone-min.js"></script>
-->
<script src="assets/jsx/tutorial_common.js"></script>
<!--
<script src="assets/jsx/tutorial1.js"></script>
-->
<!--
<script src="assets/jsx/tutorial2.js"></script>
<script src="assets/jsx/tutorial3.js"></script>
-->
<!--
<script src="assets/jsx/tutorial5.js"></script>
<script src="assets/jsx/tutorial4.js"></script>
-->
<!--
<script src="assets/jsx/tutorial6.js"></script>
<script src="assets/jsx/tutorial4.js"></script>
-->
<!--
<script src="assets/jsx/tutorial7.js"></script>
<script src="assets/jsx/tutorial4.js"></script>
-->
<!--
<script src="assets/jsx/tutorial8.js"></script>
<script src="assets/jsx/tutorial7.js"></script>
<script src="assets/jsx/tutorial10.js"></script>
<script src="assets/jsx/tutorial9.js"></script>
<!-- Each child in an array should have a unique "key" prop.
Check the renderComponent call using <undefined>.
See http://fb.me/react-warning-keys for more information. -->
<!-- 謎
<script src="assets/jsx/tutorial11.js"></script>
-->
<!--
<script src="assets/jsx/tutorial8.js"></script>
<script src="assets/jsx/tutorial7.js"></script>
<script src="assets/jsx/tutorial10.js"></script>
<script src="assets/jsx/tutorial12.js"></script>
-->
<!--
<script src="assets/jsx/tutorial7.js"></script>
<script src="assets/jsx/tutorial10.js"></script>
<script src="assets/jsx/tutorial13.js"></script>
-->
<!--
<script src="assets/jsx/tutorial7.js"></script>
<script src="assets/jsx/tutorial10.js"></script>
<script src="assets/jsx/tutorial14.js"></script>
-->
<!--
<script src="assets/jsx/tutorial15.js"></script>
-->
<!--
<script src="assets/jsx/tutorial7.js"></script>
<script src="assets/jsx/tutorial16.js"></script>
<script src="assets/jsx/tutorial17.js"></script>
-->
<!--
<script src="assets/jsx/tutorial7.js"></script>
<script src="assets/jsx/tutorial18.js"></script>
<script src="assets/jsx/tutorial19.js"></script>
-->
<script src="assets/jsx/tutorial20.js"></script>
tutorial_common.cjsx
// jQuery 使うとき
$content =
$ "#content"
.get 0
// jQuery 使わないとき
$content = document.getElementById "content"
本編
tutorial 1
tutorial.cjsx
React.render <h1>Hello, React!</h1>, $content
tutorial 2
tutorial1.cjsx
CommentList = React.createClass
render: ->
<div className="commentList">
Hello, React! I am a CommentList.
</div>
CommentForm = React.createClass
render: ->
<div className="commentForm">
Hello, React! I am a CommentForm.
</div>
tutorial 2
tutorial2.cjsx
CommentList = React.createClass
render: ->
<div className="commentList">
Hello, React! I am a CommentList.
</div>
CommentForm = React.createClass
render: ->
<div className="commentForm">
Hello, React! I am a CommentForm.
</div>
tutorial 3
tutorial3.cjsx
CommentBox = React.createClass
render: ->
<div className="commentBox">
<h1>Comments</h1>
<CommentList />
<CommentForm />
</div>
React.render <CommentBox />, $content
tutorial 4
tutorial4.cjsx
CommentList = React.createClass
render: ->
<div className="commentList">
<Comment author="Pete Hunt">This is one comment</Comment>
<Comment author="Jordan Walke">This is *another* comment</Comment>
</div>
React.render <CommentList />, $content
tutorial 5
tutorial5.cjsx
Comment = React.createClass
render: ->
<div classNmae="comment">
<h2 className="commentAuthor">
{@props.author}
</h2>
{@props.children}
</div>
tutorial 6
tutorial6.cjsx
converter = new Showdown.converter()
Comment = React.createClass
render: ->
<div className="comment">
<h2 className="commentAuthor">
{@props.author}
</h2>
{converter.makeHtml @props.children.toString()}
</div>
tutorial 7
tutorial7.cjsx
converter = new Showdown.converter()
Comment = React.createClass
render: ->
rawMarkup = converter.makeHtml @props.children.toString()
<div className="comment">
<h2 className="commentAuthor">
{@props.author}
</h2>
<span dangerouslySetInnerHTML={{__html: rawMarkup}} />
</div>
tutorial 8
tutorial8.cjsx
data_list = [
{
author: "Pete Hunt"
text: "This is one comment"
}
{
author: "Jordan Walke"
text: "This is *another* comment"
}
]
tutorial 9
tutorial9.cjsx
CommentBox = React.createClass
render: ->
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={@props.params} />
<CommentForm />
</div>
React.render <CommentBox params={data_list} />, $content
tutorial 10
tutorial10.cjsx
CommentList = React.createClass
render: ->
commentNodes = @props.data.map (comment) ->
<Comment author={comment.author}>
{comment.text}
</Comment>
<div className="commentList">
{commentNodes}
</div>
CommentForm = React.createClass
render: ->
<div className="commentForm">
Hello, React! I am a CommentForm.
</div>
tutorial 11
tutorial11.cjsx
CommentBox = React.createClass
render: ->
console.log @prop
<div className="commentBox">
<h1>Comments</h1>
</div>
React.render <CommentBox url="comments.json" />, $content
tutorial 12
tutorial12.cjsx
CommentBox = React.createClass
getInitialState: ->
data: data_list
render: ->
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={@state.data} />
<CommentForm />
</div>
React.render <CommentBox />, $content
tutorial 13
tutorial13.cjsx
CommentBox = React.createClass
getInitialState: ->
data: []
componentDidMount: ->
jqxhr = $.ajax
url: @props.url
dataType: "jsonp"
jqxhr
.done (res) =>
@setState
data: res
.fail (xhr, status, err) =>
console.error @props.url, status, err.toString()
render: ->
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={@state.data} />
<CommentForm />
</div>
React.render <CommentBox url="makejson.php" />, $content
tutorial 14
tutorial14.cjsx
CommentBox = React.createClass
loadCommentsFromServer: ->
jqxhr = $.ajax
url: @props.url
dataType: "jsonp"
jqxhr
.done (res) =>
@setState
data: res
.fail (xhr, status, err) =>
console.error @props.url, status, err.toString()
getInitialState: ->
data: []
componentDidMount: ->
@loadCommentsFromServer()
setInterval @loadCommentsFromServer, @props.pollInterval
render: ->
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={@state.data} />
<CommentForm />
</div>
React.render <CommentBox url="makejson.php" pollInterval="2000" />, $content
makejson.php
makejson.php
<?php
$data = array(
array(
'author' => 'Pete Hunt',
'text' => 'This is one comment.',
),
array(
'author' => 'Jordan Walke',
'text' => 'This is *another* comment.',
),
);
if (! isset($_GET['callback'])) {
$callback = 'callback';
} else {
$callback = $_GET['callback'];
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$data[] = $_REQUEST;
}
header('Content-type: application/json');
echo $callback.'('.json_encode($data).')';
tutorial 15
tutorial15.cjsx
CommentForm = React.createClass
render: ->
<form className="commentForm">
<input type="text" placeholder="Your name" />
<input type="text" placeholder="Say something..." />
<input type="submit" value="Post" />
</form>
CommentBox = React.createClass
render: ->
<div className="commentBox">
<h1>Comments</h1>
<CommentForm />
</div>
React.render <CommentBox />, $content
tutorial 16
tutorial16.cjsx
CommentList = React.createClass
render: ->
commentNodes = @props.data.map (comment) ->
<Comment author={comment.author}>
{comment.text}
</Comment>
<div className="commentList">
{commentNodes}
</div>
CommentForm = React.createClass
handleSubmit: (e) ->
e.preventDefault();
author = @refs.author.getDOMNode().value.trim()
text = @refs.text.getDOMNode().value.trim()
if ! text or ! author
return
# TODO: send request to the server
@refs.author.getDOMNode().value = ""
@refs.text.getDOMNode().value = ""
render: ->
<form className="commentForm" onSubmit={@handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<input type="submit" value="Post" />
</form>
tutorial 17
tutorial17.cjsx
CommentBox = React.createClass
loadCommentsFromServer: ->
jqxhr = $.ajax
url: @props.url
dataType: "jsonp"
jqxhr
.done (res) =>
@setState
data: res
.fail (xhr, status, err) =>
console.error @props.url, status, err.toString()
handleCommentSubmit: (comment) ->
console.log comment
getInitialState: ->
data: []
componentDidMount: ->
@loadCommentsFromServer()
setInterval @loadCommentsFromServer, @props.pollInterval
render: ->
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={@state.data} />
<CommentForm />
</div>
React.render <CommentBox url="makejson.php" pollInterval="2000" />, $content
tutorial 18
tutorial18.cjsx
CommentList = React.createClass
render: ->
commentNodes = @props.data.map (comment) ->
<Comment author={comment.author}>
{comment.text}
</Comment>
<div className="commentList">
{commentNodes}
</div>
CommentForm = React.createClass
handleSubmit: (e) ->
e.preventDefault();
author = @refs.author.getDOMNode().value.trim()
text = @refs.text.getDOMNode().value.trim()
if ! text or ! author
return
@props.onCommentSubmit
author: author
text: text
@refs.author.getDOMNode().value = ""
@refs.text.getDOMNode().value = ""
render: ->
<form className="commentForm" onSubmit={@handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<input type="submit" value="Post" />
</form>
tutorial 19
tutorial19.cjsx
CommentBox = React.createClass
loadCommentsFromServer: ->
jqxhr = $.ajax
url: @props.url
dataType: "jsonp"
jqxhr
.done (res) =>
@setState
data: res
.fail (xhr, status, err) =>
console.error @props.url, status, err.toString()
handleCommentSubmit: (comment) ->
jqxhr = $.ajax
url: @props.url
dataType: "jsonp"
type: "POST"
data: comment
jqxhr
.done (data) =>
@setState data:data
.fail (xhr, status, err) =>
console.error @props.url, status, err.toString()
getInitialState: ->
data: []
componentDidMount: ->
@loadCommentsFromServer()
setInterval @loadCommentsFromServer, @props.pollInterval
render: ->
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={@state.data} />
<CommentForm onCommentSubmit={@handleCommentSubmit}/>
</div>
React.render <CommentBox url="makejson.php" />, $content
tutorial 20
全部結合
tutorial20.cjsx
##
# param doc.
# converter
#
converter = new Showdown.converter()
##
# class doc.
# Comment
#
Comment = React.createClass
render: ->
rawMarkup = converter.makeHtml @props.children.toString()
<div className="comment">
<h2 className="commentAuthor">
{@props.author}
</h2>
<span dangerouslySetInnerHTML={{__html: rawMarkup}} />
</div>
##
# class doc.
# CommentList
#
CommentList = React.createClass
render: ->
commentNodes = @props.data.map (comment) ->
<Comment author={comment.author}>
{comment.text}
</Comment>
<div className="commentList">
{commentNodes}
</div>
##
# class doc.
# CommentForm
#
CommentForm = React.createClass
handleSubmit: (e) ->
e.preventDefault();
author = @refs.author.getDOMNode().value.trim()
text = @refs.text.getDOMNode().value.trim()
if ! text or ! author
return
@props.onCommentSubmit
author: author
text: text
@refs.author.getDOMNode().value = ""
@refs.text.getDOMNode().value = ""
render: ->
<form className="commentForm" onSubmit={@handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<input type="submit" value="Post" />
</form>
##
# class doc.
# CommentBox
#
CommentBox = React.createClass
loadCommentsFromServer: ->
jqxhr = $.ajax
url: @props.url
dataType: "jsonp"
jqxhr
.done (res) =>
@setState
data: res
.fail (xhr, status, err) =>
console.error @props.url, status, err.toString()
handleCommentSubmit: (comment) ->
comments = @state.data
newComment = comments.concat [comment]
@setState
data: newComment
jqxhr = $.ajax
url: @props.url
dataType: "jsonp"
type: "POST"
data: comment
jqxhr
.done (data) =>
# レスポンスは無視する
@setState
data: newComment
.fail (xhr, status, err) =>
console.error @props.url, status, err.toString()
getInitialState: ->
data: []
componentDidMount: ->
@loadCommentsFromServer()
setInterval @loadCommentsFromServer, @props.pollInterval
render: ->
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={@state.data} />
<CommentForm onCommentSubmit={@handleCommentSubmit}/>
</div>
##
# function doc.
# React.render
#
React.render <CommentBox url="makejson.php" />, $content
Congrats!