LoginSignup
8
8

More than 5 years have passed since last update.

[React] TutorialをCoffeeScript化してみた

Last updated at Posted at 2015-03-09

あらすじ

React の勉強をかねて、Tutorialに書かれているソースをCoffeeScript化してみた。

チュートリアルページ

Tutorial | React

前準備

  • 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!

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8