LoginSignup
7
8

More than 5 years have passed since last update.

React Tutorial Example (ECMAScript 2015)

Last updated at Posted at 2016-06-18

ReduxECMAScript 2015 の文法でコードを実装すると効果的です。
ECMAScript 2015(ES2015)JavaScript に新しい シンタックスオブジェクト が追加されています。
前回 のアプリケーションを ES2015 に変更してみましょう。

Learning

  • ES2015 の Import, Export を利用する。
  • ES2015 の Class, Extends を利用する。
  • ES2015 の Function, Default parameter を利用する。

Environment

  • node: v4.4.5
  • npm: v3.9.6

Comment Box Form

  • 完成される Source Code のファイルリストです。
$ tree -a -I node_modules
.
├── .babelrc
├── app.js
├── index.html
├── index.js
├── package.json
├── style.css
└── webpack.config.js

Let's hands-on

Setup application

  • git clone コマンドでアプリケーションをダウンロードします。
  • npm install コマンドで依存するモジュールをインストールします。
$ git clone https://github.com/ogom/react-comment-box-example.git
$ cd react-comment-box-example
$ git checkout redux
$ npm install

Start HTTP Server

  • npm start コマンドで Webアプリケーション を実行します。
  • ブラウザで http://localhost:4000 をロードすると Comment Box Example が表示されます。
$ npm start
$ open http://localhost:4000

(API Server は React Tutorial Example (Express) をご利用ください。)

Remove semicolons

  • まずは index.jsapp.js; を削除します。
    • Webpack で bundle すると ; は記述されるので Source Code には不要です。
    • ちなみに Redux の Examples; は記述されていません。

Add Babel preset es2015 package

  • Babel preset es2015 のモジュールをインストールします。
$ npm install babel-preset-es2015 --save-dev

Add babelrc

  • Babel preset に ES2015 plugin を設定します。
.babelrc
 {
-  "presets": ["react"]
+  "presets": ["es2015", "react"]
 }

ES2015

Containers

つぎは コンテナの index.js から ES2015 に変更します。

Import
  • requireimport に変更します。
    • import はモジュールをインポートします。
      • import Example from 'example' はモジュールの全コンテンツがインポートされます。
      • import { foo, bar } from 'example' はモジュールの対象のメンバーがインポートされます。
index.js
-var React = require('react')
-var ReactDOM = require('react-dom')
-var CommentBox = require('./app')
+import React from 'react'
+import ReactDOM from 'react-dom'
+import CommentBox from './app'

-var Redux = require('redux')
-var createStore = Redux.createStore
+import { createStore } from 'redux'

-var ReactRedux = require('react-redux')
-var Provider = ReactRedux.Provider
+import { Provider } from 'react-redux'
Const
  • varconst に変更します。
    • const は読み取り専用の値を生成します。
index.js
-var store = createStore(function(state, action) {
+const store = createStore(function(state, action) {
Function
  • function(state, action)(state, action) => に変更します。
index.js
-const store = createStore(function(state, action) {
+const store = createStore((state, action) => {
Default parameter values
  • (state, action)(state=[], action) に変更します。
    • 引数undefined の場合に初期値を設定します。
index.js
-const store = createStore((state, action) => {
-  if (state === undefined) {
-    return []
-  }
+const store = createStore((state=[], action) => {

ノイズになっていたコードが削がれて、実装したいコードに集中できるようになりました!

Components

さらに コンポーネントの app.js を ES2015 に変更します。
(以降は、さきほどのコンテナで紹介したシンタックスの説明は省略します。)

Import
  • requireimport に変更します。
app.js
-var React = require('react')
-var Remarkable = require('remarkable')
-var $ = require('jquery')
+import React from 'react'
+import Remarkable from 'remarkable'
+import $ from 'jquery'

-var ReactRedux = require('react-redux')
-var connect = ReactRedux.connect
+import { connect } from 'react-redux'
Export
  • module.exportsexport default に変更します。
    • export はモジュールをエクスポートします。
app.js
-module.exports = connect(mapStateToProps, mapDispatchToProps)(CommentBox)
+export default connect(mapStateToProps, mapDispatchToProps)(CommentBox)
Function
  • showComments: function(comments)showComments(comments) に変更します。
  • addComment: function(comments)addComment(comment) に変更します。
app.js
-var mapStateToProps = function(state) {
+const mapStateToProps = (state) => {
   return {data: state}
 }

-var mapDispatchToProps = function(dispatch) {
+const mapDispatchToProps = (dispatch) => {
   return {
-    showComments: function(comments) {
+    showComments(comments) {
       dispatch({type: 'show_comments', comments: comments})
     },
-    addComment: function(comment) {
+    addComment(comment) {
       dispatch({type: 'add_comment', comment: comment})
     }
   }
 }
Class
Comment
  • React の Component をインポートします。
  • Comment = React.createClassclass Comment extends Component に変更します。
app.js
-import React from 'react'
+import React, { Component } from 'react'

-var Comment = React.createClass({
-  rawMarkup: function() {
-    var md = new Remarkable()
-    var rawMarkup = md.render(this.props.children.toString())
+class Comment extends Component {
+  rawMarkup() {
+    const md = new Remarkable()
+    const rawMarkup = md.render(this.props.children.toString())
     return { __html: rawMarkup }
-  },
+  }

-  render: function() {
+  render() {
     return (
       <div className="comment">
         <h2 className="commentAuthor">
           {this.props.author}
         </h2>
         <span dangerouslySetInnerHTML={this.rawMarkup()} />
       </div>
     )
   }
-})
+}
CommentList
  • CommentList = React.createClassclass CommentList extends Component に変更します。
app.js
-var CommentList = React.createClass({
-  render: function() {
-    var commentNodes = this.props.data.map(function(comment) {
+class CommentList extends Component {
+  render() {
+    const commentNodes = this.props.data.map((comment) => {
       return (
         <Comment author={comment.author} key={comment.id}>
           {comment.text}
         </Comment>
       )
     })
     return (
       <div className="commentList">
         {commentNodes}
       </div>
     )
   }
-})
+}
CommentForm
  • CommentForm = React.createClassclass CommentForm extends Component に変更します。
  • getInitialStateconstructor に変更します。
  • this.handleSubmitbind(this) を追加します。
  • this.handleAuthorChangebind(this) を追加します。
  • this.handleTextChangebind(this) を追加します。
app.js
-var CommentForm = React.createClass({
-  getInitialState: function() {
-    return {author: '', text: ''}
-  },
-  handleAuthorChange: function(e) {
+class CommentForm extends Component {
+  constructor(props) {
+    super(props)
+    this.state = {author: '', text: ''}
+  }
+
+  handleAuthorChange(e) {
     this.setState({author: e.target.value})
-  },
+  }
+
-  handleTextChange: function(e) {
+  handleTextChange(e) {
     this.setState({text: e.target.value})
-  },
+  }
+
-  handleSubmit: function(e) {
+  handleSubmit(e) {
     e.preventDefault()
-    var author = this.state.author.trim()
-    var text = this.state.text.trim()
+    const author = this.state.author.trim()
+    const text = this.state.text.trim()
     if (!text || !author) {
       return
     }
     this.props.onCommentSubmit({author: author, text: text})
     this.setState({author: '', text: ''})
-  },
+  }
+
-  render: function() {
+  render() {
     return (
-      <form className="commentForm" onSubmit={this.handleSubmit}>
+      <form className="commentForm" onSubmit={this.handleSubmit.bind(this)}>
         <input
           type="text"
           placeholder="Your name"
           value={this.state.author}
-          onChange={this.handleAuthorChange}
+          onChange={this.handleAuthorChange.bind(this)}
         />
         <input
           type="text"
           placeholder="Say something..."
           value={this.state.text}
-          onChange={this.handleTextChange}
+          onChange={this.handleTextChange.bind(this)}
         />
         <input type="submit" value="Post" />
       </form>
     )
   }
-})
+}
CommentBox
  • CommentBox = React.createClassclass CommentBox extends Component に変更します。
  • getInitialStateconstructor に変更します。
  • this.loadCommentsFromServerbind(this) を追加します。
  • this.handleCommentSubmitbind(this) を追加します。
app.js
-var CommentBox = React.createClass({
-  getInitialState: function() {
-    return {data: []}
-  },
-  loadCommentsFromServer: function() {
+class CommentBox extends Component {
+  constructor(props) {
+    super(props)
+    this.state = {data: []}
+  }
+
+  loadCommentsFromServer() {
     $.ajax({
     })
-  },
+  }
+
-  handleCommentSubmit: function(comment) {
-    var comments = this.state.data
+  handleCommentSubmit(comment) {
+    const comments = this.state.data
-  },
+  }
+
-  componentDidMount: function() {
+  componentDidMount() {
     this.loadCommentsFromServer()
-    setInterval(this.loadCommentsFromServer, this.props.pollInterval)
+    setInterval(this.loadCommentsFromServer.bind(this), this.props.pollInterval)
-  },
+  }
+
-  render: function() {
+  render() {
     return (
       <div className="commentBox">
         <h1>Comments</h1>
         <CommentList data={this.props.data} />
-        <CommentForm onCommentSubmit={this.handleCommentSubmit} />
+        <CommentForm onCommentSubmit={this.handleCommentSubmit.bind(this)} />
       </div>
     )
   }
-})
+}

Congrats!


ES2015 に変更することで可読性の高いコードになりました。
次は Export と Import を利用してコードをファイルを分離 しましょう!

7
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
7
8