这个是 simple Todo with React and 的第二部 - Reflux
第一部可以看 simple Todo with React and Flux 也可以看 学习flux的一些浅显理解
Reflux 相对 Flux 来说,真的是简单很多,好理解很多。官方API 和很多开发者的分享也都说得很明白了。所以我就简单讲讲我的理解
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
从 React 0.13 开始,我们就都可以用 ES6 的语法来写 React 的组件了,具体看这里,但很多的教程都还是运用 React.createClass()
的方式,当然啦,React.createClass()
也有他的好处,例如 Autobinding
mixins
等等,但我觉得用 ES6 写会更优雅,但把原来的改写就有很多坑,所以现在就来一个一个填吧
componentWillMount
any morecomponentWillMount
这个方法已经不再需要了,我们把渲染组件之前要做的事情放在 constructor
里,例如如果我们设置我们的 state
,我们可以这样
class ExampleComponent extends React.Component {
constructor (props) {
super(props);
this.state = {
// set your state
};
}
}
改用了 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>;
}
}
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 的官方文档也写得很清楚
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
希望这篇东西可以帮到那些也想用 ES6 写 React,但总是被坑的朋友们,有问题也可以一起多加讨论,共同学习
想看完整代码的可以到 simple-todo-with-react-and-reflux
如有错误,欢迎指出 :)