Flutter 也能玩 React 的 Redux?

前言
React
开发者都知道Redux
在开发大中型 Web 应用的重要性, Flutter
作为 React
的高仿者,连 setState
都搬过来了,自然也需要把 Redux
也搬过来——好东西要一起分享。

Redux 简介
Redux
是一个单向数据流的状态管理架构,通过它能够简化应用开发、测试和维护。Flutter 的 Redux 相关插件地址:
redux:Flutter 中需要的全部
Redux
组件,例如Store
,Reducer
和Middleware
。flutter_redux:Flutter 专属的插件包,在 redux 基础上进行了封装,使得在 Flutter 中应用更为简便,例如
StoreProvider
(为组件提供Store
的基础Widget
),StoreBuilder
(从StoreProvider
中接收Store
的组件)和StoreConnector
(用于替换StoreBuilder
,可以将Store
转换为一个ViewModel
来构建组件树,一旦Store
中的State
改变了就可以重建StoreConnector
)。
在 Redux
中,通过 Store
存储了代表整个应用的状态对象 State
。每一个应用事件(不管是用户发起的或外部驱动)都被认为是一个 Action
。Action
通过 Reducer
进行调度,然后 Reducer
根据 Action
来更新 Store
中的状态。而一旦 Store
中的状态对象 State
改变了,对应的视图 View
就会反映状态的变化。

Redux
的最大特点就是可以将大部分组件进行解耦,使得 UI 界面的刷新更容易。而且,核心的业务逻辑都在 Reducer
函数中。Reducer
接收一个 Action
和当前的状态,然后返回一个新的状态对象。因此,使得单元测试更容易,我们只需要测试 Reducer
就可以测试状态业务逻辑对不对。
Redux 中间件
上面仅仅是 Redux
的第一印象,但是如果要进行异步操作,例如从接口加载数据怎么办?这个时候就需要引入新的组件,称之为中间件(Middleware)。
中间件就是在Reducer
前处理 Action
的组件。它接收当前的状态对象和要被调度的Action
,然后运行代码(如接口通讯,数据访问等)。最终,中间件可能继续使用原先的 Action
,或一个不同的 Action
,甚至什么都不做。有了中间件后,Redux
的流程图就变成了下面这样:

上代码
接下来以一个简单的记数应用为例,来演示 Redux
的基本应用。首先我们构建Redux
的三要素。
可以看到,核心业务都在 reducer
里面,reducer
根据 action
的类型更新state
,然后返回新的state
对象。action 是一个动态类型,如果简单的操作也可以是枚举,但是如果要携带新的数据或业务逻辑(例如,我们可以每次点击可以改变增加或减少的数量)使用对象会更方便。
Redux
的 Reducer
定义形式如下,即接收旧的 state
和 action
参数,然后返回新的 state
。
接下来是页面逻辑的实现了。页面逻辑有点类似。如果一个 Store 需要被下级组件使用,那么就要定义在上一级组件中。这里我们比较简单,直接定义在当前页面即可。关键的部分有以下部分:
build
的子组件使用StoreProvider
包裹,以便共享store
。需要监听
store
变化的组件使用StoreConnector
的builder
构建,并且可以使用converter
方法将store
转成组件需要的数据(即将状态数据转成ViewModel
),这里只是简单地将计数值转为了String
。在StoreConnector
方法中构建的组件,一旦状态对象发生改变后就会通知刷新。按钮事件:在按钮中执行状态对象的
dispatch
操作,以便调度对应的reducer
完成状态更新。dispatch
方法定义如下,可以看到实际上dispatch
是一组调度,这里只是调用了第一个方法,这意味着其实可以执行一系列的调度操作。
运行效果
运行效果如下所示。

总结
本篇介绍了 Redux
的基本概念和一个简单的示例,通常来说,使用Redux
的一大好处是整个状态管理的业务模式都是一致的,都必须具备 Action
,Store
,Reducer
这三个环节,这样其实也能够间接规范代码结构。同时,有了 flutter_redux
插件的适配,在 Flutter
中使用Redux
也更为简便。

版权声明: 本文为 InfoQ 作者【岛上码农】的原创文章。
原文链接:【http://xie.infoq.cn/article/fa6a38411c935ca9408a863b9】。文章转载请联系作者。
评论