Redux は ECMAScript 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.js
とapp.js
の;
を削除します。- Webpack で bundle すると
;
は記述されるので Source Code には不要です。 - ちなみに Redux の Examples に
;
は記述されていません。
- Webpack で bundle すると
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
- Learn ES2015 で ECMAScript 2015 の 基本を学習できます。
- Mozilla Developer Network は JavaScript を幅広く学習できます。
Containers
つぎは コンテナの index.js
から ES2015 に変更します。
Import
-
require
をimport
に変更します。-
import はモジュールをインポートします。
-
import Example from 'example'
はモジュールの全コンテンツがインポートされます。 -
import { foo, bar } from 'example'
はモジュールの対象のメンバーがインポートされます。
-
-
import はモジュールをインポートします。
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
-
var
をconst
に変更します。- const は読み取り専用の値を生成します。
index.js
-var store = createStore(function(state, action) {
+const store = createStore(function(state, action) {
Function
-
function(state, action)
を(state, action) =>
に変更します。- アロー関数式 は function式 より短い構文です。
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
-
require
をimport
に変更します。
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.exports
をexport 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.createClass
をclass 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.createClass
をclass 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.createClass
をclass CommentForm extends Component
に変更します。 -
getInitialState
をconstructor
に変更します。-
constructor
はクラスの コンストラクタ です。
-
-
this.handleSubmit
にbind(this)
を追加します。 -
this.handleAuthorChange
にbind(this)
を追加します。 -
this.handleTextChange
にbind(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.createClass
をclass CommentBox extends Component
に変更します。 -
getInitialState
をconstructor
に変更します。-
constructor
はクラスの コンストラクタ です。
-
-
this.loadCommentsFromServer
にbind(this)
を追加します。 -
this.handleCommentSubmit
にbind(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 を利用してコードをファイルを分離 しましょう!