百瓶技能团队\color{#FBBC05}{百瓶技能团队} 大众号@百瓶技能\color{#FBBC05}{大众号 @ 百瓶技能}
「这是我参加11月更文挑战的第3天,活动概况检查:2021终究一次更文挑战」
「百瓶 App」(各市场搜索「百瓶」体会 )在 2019 年 11 月开端接入 Flutter 时,就选定了闲鱼的 Fish Redux 作为状况管理计划。经过近两年的迭代,现已完结了 80 个以上的 Page 级功用,积累了丰厚的运用经验。虽然 GitHub1 迭代更新较少,但是它在 2021-05-18 对外宣告正在进行 「2.0 架构的演进2」以及最近释放的 「Flutter Fish_Redux 3.0起航!3」,阐明内部仍是坚持在事务中运用并且对结构进行继续优化的。
本文首要论述 Fish Redux 两大方面的常识:
- 简略介绍中心概念以及依据 Fish Redux1 的「最佳」研制流程;
- 深化分析装备式拼装。
(补白:1. 阅览本文需求对 Flutter(v1.17.1) 和 Fish Redux(v0.3.7)(或者 Redux4)有简略的了解;2. 文中的很多概念,比方 Redux、Fish Redux 等的详细介绍链接都会共同放到文末「参阅」部分)。
中心概念
- 顾名思义:源自 阿里巴巴闲鱼(Fish)技能团队,站在巨人 Redux 的肩膀上,比方 State、Action、Reducer、Store、Middleware 等概念和 Redux 完全共同。
- 青出于蓝:处理了 Redux「会集」 和「分治」间的矛盾,并且由结构主动完结从细粒度的 Reducer 到 主 Reducer 的合并进程。
- 组件三要素:
Component = View + Effect(可选) + Reducer(可选) + Dependencies(可选)
:- View(UI 视图):完全由数据驱动,担任 Dispatch 工作(Effect 和 Reducer 详细完结),组件依靠经过
ViewService
标准化调用; - Effect:处理 副作用(非修改数据的行为,包含生命周期相关的回调);
- Reducer:修改数据,并以扁平化的方式告诉组件刷新;
- Dependencies:表达组件之间的依靠关系。
- View(UI 视图):完全由数据驱动,担任 Dispatch 工作(Effect 和 Reducer 详细完结),组件依靠经过
「最佳」研制流程
假设需求完结下图 UI 的页面研制,ProtocolBuffer5(没接触过的直接了解为 API 文档即可)也现已规划结束。
那么,依据 Fish Redux 的最佳研制流程是怎么样的?
简略三步完结复杂页面的协同研制:
- 首要,进行组件拆分:拆分为五个大的组件(如图框所示,红 – profiles_component、绿 – malls_components、黄 – wallets_component、紫 – banners_component、蓝 – tools_component)。因为 Fish Redux 良好的分治策略,这时候完全可以分配给五个同学分别去完结单组件的开发(此时整个页面的目录结构如下图)。
-
其次,五位同学进行单组件的开发(以 蓝 – tools_component 为例):
-
state.dart
:结合 ProtocolBuffer5 和 UI ,界说 State 结构; -
reducer.dart
和action.dart
:分析 state 的哪些数据会被改动,界说好相应的 Action 和 Reducer; -
effect.dart
和action.dart
:分析有哪些 副作用 工作响应(比方 请求数据、页面跳转等),界说好相应的 Action 和 Effect; -
view.dart
:视图完结; -
component.dart
:装备拼装,这一步一般由 插件6 主动生成了,当然 「最佳实践」 主张删去没有用到的模块(比方很多组件的dependencies
)。
-
-
终究,Page 级拼装(后文会结合源码深化分析):
-
user_home_page/state.dart
:1. 以子组件的 State(比方ProfilesState
和ToolsState
)为中心界说 State;2. 树立 State 的 Connector。 -
user_home_page/page.dart
:装备拼装整个页面。
-
装备拼装
Fish Redux 经过 声明式装备 来将三大中心要素(View、Reducer、Effect)和依靠的子项 dependencies(子组件、middleware、adapter)完结主动拼装。 并且大部分代码都可以经过编辑器的 插件6 主动生成,仅有需求手动编写的便是
dependencies
部分。这是非常重要的一个优点,但是业界讲得比较少。 补白:装备拼装的代码跟 FishRedux Example 基本共同,可以检查相关代码 7 加深了解。
接下去,将重点论述装备拼装的两个最中心的流程:注册 和 初次页面烘托。
注册
一句代码完结用户中心页面的注册。
connecrtExtraStore
首要是完结一些大局状况的链接,重点看一下 UserHomePage()
部分。
UserHomePage()
「类图」
-
UserHomePage
:自身不需求新增任何特点或办法,按照固定范式调用 超类 相关办法完结 「页面级」 的拼装,并且在注册时对应一个仅有路由。 -
fish_redux Page()
:-
InitState<T, P> _initState
:页面初始状况,也是 Page 特有且必要的特点。 -
Widget buildPage(P param)
:初度页面烘托调用(后文会详细论述)。
-
-
fish_redux Component
:-
ViewBuilder<T> _view
:保护 View 层(buildView
特点)。
-
-
fish_redux Logic
:保护 reducer、 effect、 dependencies(所有的依靠子组成)等特点,中心逻辑处理。
dependencies
dependencies
承受两个参数(代码见上文图):
adapter
:为了处理 list 相关的性能问题,list 相关组件推荐运用;slots
:页面(或组件)依靠的子组件,这是咱们重点要了解的部分。
UHPComponentNames.tools: ToolsConnector() + ToolsComponent()
-
UHPComponentNames.tools
:依靠的姓名,String
类型表明(最佳实践主张提成一个常量,而不是直接用一个 String)。 -
ToolsConnector()
:Tools 自己管理 State,经过 ToolsConnector 与 Page State 树立链接,Page State 完全不关心 toolsState 详细有哪些特点(高内聚低耦合)! -
ToolsComponent()
:继承自Component
,除了没有InitState
和middleware
相关(包含viewMiddleware
、effectMiddleware
和adapterMiddleware
),其他跟 Page 的拼装没有差异。 -
ToolsConnector() +
:追溯到ConnOp
的 mixins –ConnOpMixin
里重载了 「加号」,终究创立了一个_Dependent
(redux_component/dependent.dart1) 实例(_Dependent<K, T>(connector: connector, logic: logic)
)。
_Dependent
的实例化,中心是创立生成 subReducer = connector.subReducer(logic.createReducer())
(下文「createReducer」相关章节会详细论述 reducer 的创立进程):
-
logic.createReducer()
:终究调用abstract class Logic
的createReducer
完结 自身 和 子组件 的 reducer 组合; -
connector.subReducer(logic.createReducer())
:copy 回来一个新的 Reducer。
至此,Page 依据 state、effect、reducer、view 以及 dependencies 完结了实例化的整个进程。
初次页面烘托
当咱们打开 UserHomePage
时,会履行如下 routes.buildPage
(即 类 Page
的 buildPage
办法),承受两个参数分别为 路由名和传入该页面的参数:
Class Page – Method buildPage
-
protectedWrapper
: 默认回来_PageWidget
, 也支撑自界说的包装(UserHomePage
中传入特点wrapper
,用的较少不用过多重视)。 - ❗️
_PageWidget
: 本质上是一个StatefulWidget
8,页面烘托的最中心部分。 - Lifecycle:Fish Redux 中默认的所有生命周期本质上来源于 Flutter Stateful Widget 的生命周期,Reducer 的生命周期和页面是共同的(
initState
->didChangeDependencies
->build
……)。
_PageWidget
重点看一下 _PageWidget()
的整个流程(中心要素类图):
_PageWidget()
中 initState()
和 build()
相关的履行进程:
_PageWidget()
– initState
中最重要的 createStore
的操作:
-
_initState(param)
: UserHomePage 中界说的initState
在这里调用,承受路由参数对 State 进行初始化操作。 -
createReducer()
进程中最中心的是combineReducers
:- 入参
[protectedReducer, protectedDependenciesReducer]
: 1.protectedReducer
便是咱们自己在reducer.dart
文件中界说的buildReducer()
; 2.protectedDependenciesReducer
指的便是 依靠的子组件的 reducer,也是经过类似combineReducers
的方式生成的(后文「createReducer – 生成子组件的 Reducer」部分再来看一下这个进程 )。 -
combineReducers
:会做一些 reducer 的判空过滤,终究回来一个 colsure —— Reducer,在后续的 dispatch 相关操作时会履行。
- 入参
createReducer – 生成子组件的 Reducer
-
slots
便是咱们在page.dart
中界说的依靠子组件,createReducer()
中经过循环遍历创立子组件(createSubReducer()
)的reducer
列表,终究经过上文中相同的combineReducers
以及combineSubReducers
把 reducer 结合起来。 -
createSubReducer()
终究是履行connector.subReducer(logic.createReducer())
(redux_component/dependent.dart):-
logic.createReducer()
其实便是履行logic.dart
中的createReducer()
。 -
connector.subReducer(…)
终究履行MutableConn
的subReducer()
:-
get
:上文ToolsConnector
父子组件状况连接器中自己界说的,让子组件获取相应状况数据; - 依据 action 和 props 生成新的状况,并且与老的 state 进行对比;
- 如果有改动 clone 一份新的回来,并且告诉 view 改动相应状况,否则直接回来当前 state。
-
-
-
combineReducers
与上文共同,combineSubReducers
中心终究仍是会调用 上文中的subReducer
。
_PageWidget()
– build()
相关操作
build()
终究调用链路会到 ComponentWidget
, 也是一个 StatefulWidget
,首要做了两件工作:
-
void initState()
:依据 store、bus 等创立一个 context,这个 context 会在整个页面周期中运用。比方页面中烘托子组件的操作 ——viewService.buildComponent('your-component-name')
。 -
Widget build(BuildContext context)
: 真正创立视图的地方
以上便是 Fish Redux 整个主动装备拼装的进程,也简略说了下初次烘托的部分。
终究
源码解析部分并没有把所有细节都论述,如果感兴趣的朋友欢迎一起探讨。
有任何问题欢迎重视 「百瓶技能」大众号后发消息发问,会第一时间回复。
更多精彩请重视咱们的大众号“ 百瓶技能 ”,有不定期福利呦!
参阅
Footnotes
-
GitHub Fish Redux 源码 (2019-03-06 开源)github.com/alibaba/fis… ↩ ↩2 ↩3
-
闲鱼技能:Flutter Fish Redux 架构演进 2.0 (2021-05-18)mp.weixin.qq.com/s/8vFDLq3Wa…) ↩
-
Flutter Fish_Redux 3.0起航!:mp.weixin.qq.com/s/YYyU2yoM6… ↩
-
Redux redux.js.org ↩
-
Google Protocol Buffers: developers.google.com/protocol-bu… ↩ ↩2
-
Visual Studio Code Fish Redux Template Extension: marketplace.visualstudio.com/items?itemN… ↩ ↩2
-
Fish Redux 官方比如:github.com/alibaba/fis… ↩
-
Flutter StatefulWidget: api.flutter.dev/flutter/wid… [9]: Fish Redux 官方文档:github.com/alibaba/fis… ↩