这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战
前言
我们花了7篇介绍了 Redux
在 Flutter
中的应用,以及特点,本篇对这一系列进行总结,然后我们再介绍其他状态管理插件。
Redux 的基本元素
Redux
的基本元素有4个:Store
,Action
,Reducer
和 View
,4个元素直接的数据流动是单向的,如下图所示:
Store
存储View
所需的状态数据;View
在接收到用户交互事件后,调度Action
;Action
会被传递到Reducer
中,Reducer
根据Action
处理对应的业务,然后返回新的状态数据。- 新的状态数据通过
Store
驱动视图View
进行更新。
关于 Redux
的基本介绍和示例的请看这篇:Flutter入门与实战(五十八): 看 Flutter 如何分享 React 的 Redux状态管理。由于 Redux
本身是从 React
来的,因此想深入了解的也可以参考 Redux
的官网:Redux - A Predictable State Container for JS Apps。
中间件
在某些场景下,我们在处理 Action
前可能需要做一些前置处理或异步处理,这个时候就可以使用中间件。中间件其实就是拦截器的概念。有了中间件后,Redux
的数据流变成了下面的样子:
在中间件中,可以发起新的
Action
(比如获取到新的状态数据后),也可以什么都不做(比如仅仅是发起一个无需确认的后端请求,或者仅仅是存储离线数据)。关于中间件可以阅读如下篇章:
中间件代码优化
中间件最简单的写法是使用不同的if...else
,但是如果 Action
很多的时候,会导致 if...else
过多甚至嵌套,代码难以维护。这个时候可以利用TypedMiddleware
将中间件方法与对应的Action
进行绑定,从而无需使用 if...else
进行Action
类型判断,增强代码的可维护性。我们开发了一个通用的购物车数量加减组件来演示TypedMiddleware
的使用:Flutter 入门与实战(六十二):开发一个通用的购物车数量加减组件。
多组件状态共享
和 Provider
类似,如果多个组件要共享一个 Redux
的 Store
对象,这些组件需要在 StoreProvider
下的子组件中。对于全局的 Store
共享数据(例如登录用户信息),可以将 StoreProvider
放置在顶级应用。我们通过购物清单这个应用讲述了多个组件如何共享 Store
状态:Flutter 入门与实战(六十):以购物清单为例讲述 Redux 的状态如何多组件共享。当然,从性能考虑,非必要时,尽快使用局部的Store
。
性能优化
在实际测试中发现,StoreConnector在状态发生改变的时候,只会刷新它的下级组件,而不是 Store 的下级组件。这使得我们有了一个性能优化的原则 —— 尽可能地缩小 StoreConnector 覆盖的组件范围,从而避免过多的组件刷新,进而提高性能。我们也从源码角度分析了为什么能够达到这样的效果:Flutter 入门与实战(六十四):这篇很长,为了性能,你忍一下 —— 从源码看 flutter_redux精准刷新。
对于顶级 Store,如同我们在Flutter 入门与实战(六十三):Redux之利用 distinct 属性进行性能优化这一篇介绍的,顶级Store
可能会导致全局刷新,因此最好是将 distinct
属性设置为 true
,并且实现 Store
状态对象类的==
和 hashCode
方法,从而可以避免每次 Action
都引起全局的组件刷新。前面提到的将 distinct
属性设置为 true
,并且实现 Store
状态对象类的==
和 hashCode
方法,也能够避免无谓的全局刷新,提高性能。
总结
Redux
因为单向数据流的机制,以及各个元素的相互分工协作,使得使用 Redux
编写的代码会更规范,也易于理解。因此,更适用于中大型应用。加上flutter_redux
的封装,极大地简化了 Redux
在 Flutter
中的使用。实际上,Redux
还有更多内容等待我们去发掘,建议通过阅读源码和官网文档,去了解更多关于 Redux
的应用和特点。
我是岛上码农,微信公众号同名,这是Flutter 入门与实战的专栏文章,对应源码请看这里:Flutter 入门与实战专栏源码。
👍🏻:觉得有收获请点个赞鼓励一下!
🌟:收藏文章,方便回看哦!
💬:评论交流,互相进步!