How to Write React in ES6
原文链接 http://jasonliao.me/posts/2015-09-29-how-to-write-react-in-es6.html
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。
这个是 simple Todo with React and 的第二部 - Reflux
第一部可以看 simple Todo with React and Flux 也可以看 学习flux的一些浅显理解
Reflux 相对 Flux 来说,真的是简单很多,好理解很多。官方API 和很多开发者的分享也都说得很明白了。所以我就简单讲讲我的理解
How Reflux Works
Reflux 给我们封装了一些方法和属性,可以让我们的数据和操作可以在 Actions Stores Components 之间单向流动,不再需要 Dispatcher
用
Reflux.createStore()
方法创建的 Store 可以添加一个listenables
的属性,只要把我们的 Actions 放在里面,当我们执行 Actions 里的行动的时候,就会自动触发 Store 里的on"Actions"
的方法,就这完成了 Actions -> Stores而在 Controller View 中,有
Store.listen(fn)
方法,只要 Store 执行了this.toggle()
,就会触发这个在 Controller View 里的fn
函数,我们就可以在这个fn
里改变state
的值, Components 也会随之变化,这就完成了 Stores -> View Components而在任意的 Components 内直接触发 Actions 的行动,就可以完成 View Components -> Actions
Refactoring React Components to ES6 Classes
从 React 0.13 开始,我们就都可以用 ES6 的语法来写 React 的组件了,具体看这里,但很多的教程都还是运用 React.createClass()
的方式,当然啦,React.createClass()
也有他的好处,例如 Autobinding
mixins
等等,但我觉得用 ES6 写会更优雅,但把原来的改写就有很多坑,所以现在就来一个一个填吧
1. We don't need componentWillMount
any more
componentWillMount
这个方法已经不再需要了,我们把渲染组件之前要做的事情放在 constructor
里,例如如果我们设置我们的 state
,我们可以这样
class ExampleComponent extends React.Component {
constructor (props) {
super(props);
this.state = {
// set your state
};
}
}
2. Autobinding and No Autobinding
改用了 ES6 的语法之后,函数的 this
不再是绑定在了自身的实例身上,这里可以有两个方法去解决这个问题
use arrow function
=>
当你在组件里写的方法是用 arrow function,那么
this
就会自动绑在实例身上,后面调用方法的时候,就可以直接调用了class ExampleComponent extends React.Component { constructor (props) { super(props); } _handleClick: () => { console.log(this); // this is an ExampleComponent } render () { return <div onClick={this._handleClick}>Hello, Reactr!</div>; } }
use
bind(this)
还有一种就是利用
bind(this)
// use bind(this) when called class ExampleComponent extends React.Component { constructor (props) { super(props); } _handleClick () { console.log(this); // this is an ExampleComponent } render () { return <div onClick={this._handleClick.bind(this)}>Hello, Reactr!</div>; } } // use bind(this) in constructor class ExampleComponent extends React.Component { constructor (props) { super(props); this._handleClick = this._handleClick.bind(this); } _handleClick () { console.log(this); // this is an ExampleComponent } render () { return <div onClick={this._handleClick}>Hello, Reactr!</div>; } }
3. No Mixins
ES6 不支持 mixins 了,but Mixins Are Dead. Long Live Composition
Reflux 官方的 TodoApp 有 mixins,那我们怎么来修改他呢
TodoApp 里的
mixins: [Reflux.connect(TodoStores,"list")]
Reflux.connect
方法主要作用是当 TodoStores 执行this.toggle()
方法的时候,TodoApp 就会重新setState
来更新数据,所以我们可以用 TodoStores 的listen
方法来监听,再调用 TodoApp 自身的onStateChange
方法TodoMain 里的
mixins: [ ReactRouter.State ]
这个在 react-router 1.0.0 之后就不再有了,UPGRADE_GUIDE也写得很明白了,只要把
switch
里的getPath()
改成this.props.location.pathname
就可以了TodoItem 里的
mixins: [React.addons.LinkedStateMixin]
这个是用来做
input
数据双向绑定的,不用 mixins 怎么做,React 的官方文档也写得很清楚
Use React-Router 1.0.0-rc1
npm install react-router@1.0.0-rc1
好像用上面的命令才可以下到 1.0.0 不然直接 npm install react-router
下的还是 0.13 的
Reflux 官方的 TodoApp 用的 react-router 是 0.13 版的,但现在出到 1.0 了,UPGRADE_GUIDE 也写得很明白了,所以还是用 1.0 的吧
而在这个 TodoApp 中,受到影响的就是 Rendering、Links、RouteHandler 和 State mixin
Summary
希望这篇东西可以帮到那些也想用 ES6 写 React,但总是被坑的朋友们,有问题也可以一起多加讨论,共同学习
想看完整代码的可以到 simple-todo-with-react-and-reflux
如有错误,欢迎指出 :)