Redux 入门了解

2017/02/09 09:34
阅读数 31

Redux 入门了解

React Flux架构

  • Flux是Facebook 用来构建客户端Web应用的应用架构。它利用单向数据流的方式来组合React中的视图组件。它更像一个模式而不是一个正式的框架,开发者不需要太多的新代码就可以快速的上手Flux。
    image

1. dispatcher

  • 事件调度中心,flux模型的中心枢纽,管理着Flux应用中的所有数据流。
  • 它本质上是Store的回调注册。每个Store注册它自己并提供一个回调函数。
  • 当Dispatcher响应Action时,通过已注册的回调函数,将Action提供的数据负载发送给应用中的所有Store。
  • 应用层级单例!!

2. store

  • 负责封装应用的业务逻辑跟数据的交互。
  • Store中包含应用所有的数据
  • Store是应用中唯一的数据发生变更的地方
  • Store中没有赋值接口—所有数据变更都是由dispatcher发送到store,新的数据随着Store触发的change事件传回view。
  • Store对外只暴露getter,不允许提供setter!!
  • 禁止在任何地方直接操作Store

3. view

  • controller-view 可以理解成MVC模型中的controller,它一般由应用的顶层容器充当,负责从store中获取数据并将数据传递到子组件中。
  • 简单的应用一般只有一个controller-view,复杂应用中也可以有多个。controller-view是应用中唯一可以操作state的地方(setState())
  • view(UI组件) ui-component 职责单一只允许调用action触发事件,
  • 数据从由上层容器通过属性传递过来。

4. 其他

  • action creators 作为dispatcher的辅助函数,
  • 通常可以认为是Flux中的第四部分。
  • ActionCreators是相对独立的,它作为语法上的辅助函数以action的形式使得dispatcher传递数据更为便利。

image

Flux的优势

    1. 数据状态变得稳定同时行为可预测

    因为angular双向绑定的原因,我们永远无法知道数据在哪一刻处于稳定状态,所以我们经常会在angular中看到通过setTimeout的方式处理一些问题(其实有更优雅的解决方案,不在本次讨论之内)。同时由于双向绑定的原因,行为的流向我们也很难预测,当视图的model变多的时候,如果再加上一堆子视图依赖这些model,问题发生时定位简直是噩梦啊(这也是angular的错误信息那么不友好的原因,因为框架开发者也无法确定当前行为是谁触发的啊,绑定的人太多了…)。但是这里还是要强调一点就是,并不是说双向绑定就一定会导致不稳定的数据状>态,在angular中我们通过一些手段依然可以使得数据变得稳定,只是双向绑定(mvvm)相对于flux更容易引发数据不稳定的问题。

    1. 所有的数据变更都发生在store里

    flux里view是不允许直接修改store的,view能做的只是触发action,然后action通过dispatcher调度最后才会流到store。所有数据的更改都发生在store组件内部,store对外只提供get接口,set行为都发生在内部。store里包含所有相关的数据及业务逻辑。所有store相关数据处理逻辑都集中在一起,避免业务逻辑分散降低维护成本。

    1. 数据的渲染是自上而下的

    view所有的数据来源只应该是从属性中传递过来的,view的所有表现由上层控制视图(controller-view)的状态决定。我们可以把controller-view理解为容器组件,这个容器组件中包含若干细小的子组件,容器组件不同的状态对应不同的数据,子组件不能有自己的状态。也就是,数据由store传递到controller-view中之后,controller-view通过setState将数据通过属性的方式自上而下传递给各个子view。

    1. view层变得很薄,真正的组件化

    由于2、3两条原因,view自身需要做的事情就变得很少了。业务逻辑被store做了,状态变更被controller-view做了,view自己需要做的只是根据交互触发不同的action,仅此而已。这样带来的好处就是,整个view层变得很薄很纯粹,完全的只关注ui层的交互,各个view组件之前完全是松耦合的,大大提高了view组件的复用性。

    1. dispatcher是单例的

    对单个应用而言dispatcher是单例的,最主要的是dispatcher是数据的分发中心,所有的数据都需要流经dispatcher,dispatcher管理不同action于store之间的关系。因为所有数据都必须在dispatcher这里留下一笔,基于此我们可以做很多有趣的事情,各种debug工具、动作回滚、日志记录甚至权限拦截之类的都是可以的。

Flux的困境

    1. 过多的样板代码

    flux只是一个架构模式,并不是一个已实现好的框架,所以基于这个模式我们需要写很多样板代码,代码量duang的一下子上来了。。不过好在目前已经有很多好用的基于flux的第三方实现,目前最火的属redux。

    1. dispatcher是单例

    dispatcher作为flux中的事件分发中心,同时还要管理所有store中的事件。当应用中事件一多起来事件时序的管理变得复杂难以维护,没有一个统一的地方能清晰的表达出dispatcher管理了哪些store。

    1. 异步处理到底写在哪里

    按flux流程,action中处理:依赖该action的组件被迫耦合进业务逻辑
    按store职责在store中处理:store状态变得不稳定,dispatcher的waitFor失效

Redux

Facebook官方提出了FLUX思想管理数据流,同时也给出了自己的实现来管理React应用。可是当我打开FLUX的文档时候,繁琐的实现,又臭又长的文档,实在难以实现, 所以github上涌现了一批关于实现FLUX的框架,比较出名的有Redux, Reflux, Flummox。

其中Redux的简单和有趣的编程体验吸引很多追随着。

  • 简单。和其它的FLUX实现不一样,Redux只有唯一的state树,不管项目变的有多复杂,只需要管理一个State树。可能你会有疑问,一个state树就够用了?这个state树该有多大?别着急,Redux中的Reducer机制可以解决这个问题。

  • 有趣。忙于迭代项目的程序员,体会编程带来的趣味是有多久没有体会到了?瞧下面这张图,右边那个调试工具是啥?整个应用的action和state都这么被轻松的管理了?行为还能被保存,删除,回滚,重置?修改了代码,页面不刷新也能产生变化?别开玩笑了,不行,世界那么大,让我去试试!

Redux思路

注意:图片仅仅是FLUX思想,而不是Facebook的实现。
理解流程:
  ╔═══════╗       ╔══════╗       ╔══════════════╗
  ║ Actions ║────>║ Stores║───>║ View Components ║
  ╚═══════╝       ╚══════╝       ╚══════════════╝
       ^                                      │
       └──────────────────────┘

完整流程:  

  ╔═════════╗    ╔═════════╗   ╔══════╗   ╔══════╗    ╔═══════════════╗
  ║ Actions  ║──>║Middlewares║─>║Reducer ║─>║ Stores║──>║ View Components ║
  ╚═════════╝    ╚═════════╝   ╚══════╝   ╚══════╝    ╚═══════════════╝
       ^                                                         │
       ───────────────────────────────────┘
  • View层不能直接对state进行操作,
  • 而需要依赖Actions派发指令来告知Store修改状态,
  • Store接收Actions指令后发生相应的改变,
  • View层同时跟着Store的变化而变化。
  • ========================
  • Action 层处理动作事件,
  • Middlewares中间件, 很多 Redux 插件都是基于些入口点
  • Reducer处理 Store 状态数据
  • Stores 层是统一状态数据存储
  • View层接收状态的视图层

Redux属性

  • 每一个reducer对应一个 Store, 单独管理自己的状态数据
  • 若共用状态数据时, 页面时空内的状态是一样的
    • 若 A 页面处理的状态数据, B 页面也共用些数据, 那么 B 页面的状态在 A 页面改变时他也跟着改变
    • 若状态数据是时间上逻辑上的状态, 此特性会是一个很糟糕的情况, 如数据区分不同态, 当第一次A 页面处理完各个环节后, 第 n 次的进入 A 页面都是第一次的最后环节状态数据
  • 有时态的状态数据最终会成为一个脏数据
  • 采用遍历方式查找目标Reducer, 会是庞大的项目鸡肋

参考

Flux架构入门教程-阮一峰的网络日志
Redux官方
李剑飞微博
谈一谈我对 React Flux 架构的理解
使用Redux管理你的React应用

展开阅读全文
打赏
0
2 收藏
分享
加载中
更多评论
打赏
0 评论
2 收藏
0
分享
返回顶部
顶部