重磅消息,Redux 1.0 发布,终于能够放心用于生产环境了!前端
在这个端应用技术膨胀的时代,天天都有一大堆框架冒出,号称解决了 XYZ 等一系列牛 X 的问题,而后过一段时间就不被提起了。但开发的应用仍是须要维护的!因此选择框架时不要只顾着本身用着爽,还要想着之后别人接手时的难易度。react
由于 Flux 自己约定不够细致,如何作异步、如何作同构这些很是广泛的问题,官方都没有给出详细的说明。还有 store,view 里一大堆重复代码,极速膨胀的 action 等问题。这也不免会冒出一堆“改良”性的轮子。有一些很是闪光,如 Redux,Reflux,Marty。Reflux 和 Marty 基本上只是去掉重复代码并为现有 Store,Action 增长一些灵活性,用起来比原生 Flux 上手更容易,可是整体两者没有跳出 Flux 的思想,大量依旧采用“传统”的 mixin 方式实现。若是项目不是很复杂能够试试。至于 Relay,因为须要后端 GraphQL 支持,对于采用 REST 接口开发的遗留项目和先后端分离的大团队来讲成本切换有点高。git
如今开始说今天的主角 Redux。Redux 由 Flux 演变而来,后来受 Elm 启发,去掉了 Flux 的复杂性,到如今愈来愈自成一派,甚至已经有了 Angular 的实现。最近开始把团队旧的纯 Flux 开发项目逐步往 Redux 上迁移。Redux 仍是秉承了 Flux 单向数据流、Store is the single source of truth 的思想,这两点略过。下面谈一下使用 Redux 过程当中的其它感觉。github
Redux 文档很是清晰细致,这一点有助于统一团队编码风格,节省了不少纠结和踩坑的时间。不再纠结 Ajax 请求到底放哪里了,所有丢到 action(通用的也能够放到 middleware) 里就没错。究竟使用 state 仍是 props?组件里所有使用 props,只在顶层组件里使用 state。以前为了灵活或兼容性,Redux 的 provider 提供 Provider
decorator 装饰器 和 provider
两种调用用法,如今只建议使用 Provider
decorator。Redux 这点设计思想和 Python 的很是像:编程
There should be one, and preferably only one - obvious way to do it.redux
你会发现用了 Redux 后,整个团队写的代码风格都比较一致,上一次有这种感觉是项目由旧的 jQuery 组件迁到 React 的时候。若是有些场景你仍是纠结怎么办?去 Redux issues 提个 issue 吧,很快就会有人回复。后端
前端复杂性在于 view,view 复杂性在于 state 处理。state 复杂是由于包括了 AJAX 返回的数据、当前显示的是哪一个 tab 等这些 UI state、表单状态、甚至还有当前的 url 等。Redux 把这些全部的 state 汇总成一个大的对象,起了个名字叫 Store
,没错,就是 Flux 里的 Store
。只是 Redux 限定一个应用只能有一个 Store
。单一 Store
带来的好处是,全部数据结果集中化,操做时的便利,只要把它传给最外层组件,那么内层组件就不须要维持 state,所有经父级由 props 往下传便可。子组件变得异常简单。app
只有一个 Store
,第一感受是这个 Store
对象会不会很是大?其实对象大并不可怕,可怕的是对象处理逻辑放到一块儿。只要把这些处理逻辑按处理内容拆分不就能够了吗?!拆分后的每块处理逻辑就是一个 Reducer
。把这些 Reducer
里的每块内容合到一块儿(用 ES6 的 import 语法)就组成了完整的 Store
。Reducer
只是一个纯函数,因此很容易测试。提到 Reducer
不得不提函数式编程,reducer 本质就是作对象格式转换,这点用函数式操做实在过高效了。框架
(previousState, action) => newState
由于是纯函数,组合多个 reducer 很是简单,参见 https://gist.github.com/gaearon/d77ca812015c0356654f。顺便也移除了 Flux 里最让人诟病的 waitFor
语法。前后端分离
Redux 的 action 与 Flux 中的相似,都是表达 view 要改变 store 内容的载体。Flux 是经过统一的 Dispatcher
分发 action,Redux 去除了这个 Dispatcher
,使用 store 的 store.dispatch()
方法来把 action 传给 store。因为全部的 action 处理都会通过这个 store.dispatch()
方法,Redux 聪明地利用这一点,实现了与 Koa,Ruby Rack 相似的 Middleware 机制。Middleware 可让你在 dispatch action 后,到达 store 前这一段拦截并插入代码,能够任意操做 action 和 store。很容易实现灵活的日志打印、错误收集、API 请求、路由等操做。咱们团队根据预创建的 action 和请求间的映射直接在这里直接发 Ajax 请求,今后麻麻不再用担忧我异步取数据了。
除了这些以外,还有逆天的 DevTools,可让应用像录像机同样反复录制和重放。
对于同构应用 Redux 也有很好的支持,这一块团队正在调研,等实际上线后再作分享。
固然使用过程当中也有一些不顺利的地方,其实主要仍是思想方面的转变。
这也被称为 Smart Component 和 Dumb Component 之间的选择,组件库开发应尽量作成 Dumb Component。这一点和传统的 jQuery 类广泛使用命令式语法作组件开发有很大不一样。如写一个 Dialog,jQuery 组件通常会提供 dialog.show()
, dialog.hide()
方法。但 Redux 要求显示或隐藏应该被看成一个 props,由外部传入来控制。Redux 比 Flux 更严格要求 Store 做为数据来源的唯一性,因此以前能用的组件如今发现直接不能用了。
请求的发起要在 action 里作,可是请求的暂停/启动状态要放到 store 里,会增长一些复杂性,但保证了数据的一致性。其实仍是未明确 store 是单一数据源的思想。
官方地址:https://github.com/rackt/redux
中文文档:http://github.com/camsong/redux-in-chinese
项目列表:https://github.com/xgrommx/awesome-redux
同构示例:http://react-redux.herokuapp.com/
对了,据说中文文档翻译的还不错,连 Redux 做者 Dan Abramov 都推了,要不你也看看。有精力一块儿参与翻译,没有精力给个 star 也行。