Flutter 状态管理-Fish Redux 是如何完成配置组装的


百瓶技能团队\color{#FBBC05}{百瓶技能团队} 大众号@百瓶技能\color{#FBBC05}{大众号 @ 百瓶技能}

Flutter 状态管理-Fish Redux 是如何完成配置组装的
Flutter 状态管理-Fish Redux 是如何完成配置组装的

「这是我参加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 两大方面的常识:

  1. 简略介绍中心概念以及依据 Fish Redux1 的「最佳」研制流程;
  2. 深化分析装备式拼装

(补白: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:表达组件之间的依靠关系。

「最佳」研制流程

假设需求完结下图 UI 的页面研制,ProtocolBuffer5(没接触过的直接了解为 API 文档即可)也现已规划结束。

那么,依据 Fish Redux 的最佳研制流程是怎么样的?

Flutter 状态管理-Fish Redux 是如何完成配置组装的

简略三步完结复杂页面的协同研制:

  • 首要,进行组件拆分:拆分为五个大的组件(如图框所示,红 – profiles_component、绿 – malls_components、黄 – wallets_component、紫 – banners_component、蓝 – tools_component)。因为 Fish Redux 良好的分治策略,这时候完全可以分配给五个同学分别去完结单组件的开发(此时整个页面的目录结构如下图)。
    Flutter 状态管理-Fish Redux 是如何完成配置组装的
  • 其次,五位同学进行单组件的开发(以 蓝 – tools_component 为例)
    • state.dart:结合 ProtocolBuffer5 和 UI ,界说 State 结构;
    • reducer.dartaction.dart:分析 state 的哪些数据会被改动,界说好相应的 Action 和 Reducer;
    • effect.dartaction.dart:分析有哪些 副作用 工作响应(比方 请求数据、页面跳转等),界说好相应的 Action 和 Effect;
    • view.dart:视图完结;
    • component.dart:装备拼装,这一步一般由 插件6 主动生成了,当然 「最佳实践」 主张删去没有用到的模块(比方很多组件的 dependencies)。
  • 终究,Page 级拼装(后文会结合源码深化分析)
    • user_home_page/state.dart:1. 以子组件的 State(比方 ProfilesStateToolsState)为中心界说 State;2. 树立 State 的 Connector。
    • user_home_page/page.dart:装备拼装整个页面。

装备拼装

Fish Redux 经过 声明式装备 来将三大中心要素(View、Reducer、Effect)和依靠的子项 dependencies(子组件、middleware、adapter)完结主动拼装。 并且大部分代码都可以经过编辑器的 插件6 主动生成,仅有需求手动编写的便是 dependencies 部分。这是非常重要的一个优点,但是业界讲得比较少。 补白:装备拼装的代码跟 FishRedux Example 基本共同,可以检查相关代码 7 加深了解。

接下去,将重点论述装备拼装的两个最中心的流程:注册 和 初次页面烘托。

注册

一句代码完结用户中心页面的注册。

Flutter 状态管理-Fish Redux 是如何完成配置组装的

connecrtExtraStore 首要是完结一些大局状况的链接,重点看一下 UserHomePage() 部分。

Flutter 状态管理-Fish Redux 是如何完成配置组装的

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(所有的依靠子组成)等特点,中心逻辑处理。

Flutter 状态管理-Fish Redux 是如何完成配置组装的

dependencies

dependencies 承受两个参数(代码见上文图):

  1. adapter:为了处理 list 相关的性能问题,list 相关组件推荐运用;
  2. slots:页面(或组件)依靠的子组件,这是咱们重点要了解的部分。

UHPComponentNames.tools: ToolsConnector() + ToolsComponent()

  • UHPComponentNames.tools:依靠的姓名,String 类型表明(最佳实践主张提成一个常量,而不是直接用一个 String)。
  • ToolsConnector():Tools 自己管理 State,经过 ToolsConnector 与 Page State 树立链接,Page State 完全不关心 toolsState 详细有哪些特点(高内聚低耦合)!
    Flutter 状态管理-Fish Redux 是如何完成配置组装的
  • ToolsComponent():继承自 Component,除了没有 InitStatemiddleware 相关(包含 viewMiddlewareeffectMiddlewareadapterMiddleware),其他跟 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 的创立进程)

Flutter 状态管理-Fish Redux 是如何完成配置组装的

  1. logic.createReducer():终究调用 abstract class LogiccreateReducer 完结 自身 和 子组件 的 reducer 组合;
  2. connector.subReducer(logic.createReducer()):copy 回来一个新的 Reducer。

至此,Page 依据 state、effect、reducer、view 以及 dependencies 完结了实例化的整个进程。

初次页面烘托

当咱们打开 UserHomePage 时,会履行如下 routes.buildPage(即 类 PagebuildPage 办法),承受两个参数分别为 路由名和传入该页面的参数:

Flutter 状态管理-Fish Redux 是如何完成配置组装的

Class Page – Method buildPage

Flutter 状态管理-Fish Redux 是如何完成配置组装的

  • protectedWrapper: 默认回来 _PageWidget, 也支撑自界说的包装(UserHomePage 中传入特点 wrapper ,用的较少不用过多重视)。
  • ❗️_PageWidget: 本质上是一个 StatefulWidget8,页面烘托的最中心部分
  • Lifecycle:Fish Redux 中默认的所有生命周期本质上来源于 Flutter Stateful Widget 的生命周期,Reducer 的生命周期和页面是共同的(initState -> didChangeDependencies -> build……)。

_PageWidget

重点看一下 _PageWidget() 的整个流程(中心要素类图):

Flutter 状态管理-Fish Redux 是如何完成配置组装的

_PageWidget()initState()build() 相关的履行进程:

Flutter 状态管理-Fish Redux 是如何完成配置组装的

_PageWidget()initState 中最重要的 createStore 的操作:

Flutter 状态管理-Fish Redux 是如何完成配置组装的

  • _initState(param): UserHomePage 中界说的 initState 在这里调用,承受路由参数对 State 进行初始化操作。
  • createReducer() 进程中最中心的是 combineReducers
    Flutter 状态管理-Fish Redux 是如何完成配置组装的
    • 入参 [protectedReducer, protectedDependenciesReducer]: 1. protectedReducer 便是咱们自己在 reducer.dart 文件中界说的 buildReducer(); 2. protectedDependenciesReducer 指的便是 依靠的子组件的 reducer,也是经过类似 combineReducers 的方式生成的(后文「createReducer – 生成子组件的 Reducer」部分再来看一下这个进程 )。
    • combineReducers:会做一些 reducer 的判空过滤,终究回来一个 colsure —— Reducer,在后续的 dispatch 相关操作时会履行。
createReducer – 生成子组件的 Reducer

Flutter 状态管理-Fish Redux 是如何完成配置组装的

  • 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(…) 终究履行 MutableConnsubReducer()
      Flutter 状态管理-Fish Redux 是如何完成配置组装的
      1. get :上文 ToolsConnector 父子组件状况连接器中自己界说的,让子组件获取相应状况数据;
      2. 依据 action 和 props 生成新的状况,并且与老的 state 进行对比;
      3. 如果有改动 clone 一份新的回来,并且告诉 view 改动相应状况,否则直接回来当前 state。
  • combineReducers 与上文共同, combineSubReducers 中心终究仍是会调用 上文中的 subReducer
_PageWidget()build() 相关操作

Flutter 状态管理-Fish Redux 是如何完成配置组装的

build() 终究调用链路会到 ComponentWidget, 也是一个 StatefulWidget,首要做了两件工作:

  1. void initState() :依据 store、bus 等创立一个 context,这个 context 会在整个页面周期中运用。比方页面中烘托子组件的操作 —— viewService.buildComponent('your-component-name')
  2. Widget build(BuildContext context): 真正创立视图的地方
    Flutter 状态管理-Fish Redux 是如何完成配置组装的

以上便是 Fish Redux 整个主动装备拼装的进程,也简略说了下初次烘托的部分。

终究

源码解析部分并没有把所有细节都论述,如果感兴趣的朋友欢迎一起探讨。

有任何问题欢迎重视 「百瓶技能」大众号后发消息发问,会第一时间回复。

更多精彩请重视咱们的大众号“ 百瓶技能 ”,有不定期福利呦!

Flutter 状态管理-Fish Redux 是如何完成配置组装的

参阅

Footnotes

  1. GitHub Fish Redux 源码 (2019-03-06 开源)github.com/alibaba/fis… ↩ ↩23

  2. 闲鱼技能:Flutter Fish Redux 架构演进 2.0 (2021-05-18)mp.weixin.qq.com/s/8vFDLq3Wa…) ↩

  3. Flutter Fish_Redux 3.0起航!:mp.weixin.qq.com/s/YYyU2yoM6… ↩

  4. Redux redux.js.org ↩

  5. Google Protocol Buffers: developers.google.com/protocol-bu… ↩ ↩2

  6. Visual Studio Code Fish Redux Template Extension: marketplace.visualstudio.com/items?itemN… ↩ ↩2

  7. Fish Redux 官方比如:github.com/alibaba/fis… ↩

  8. Flutter StatefulWidget: api.flutter.dev/flutter/wid… [9]: Fish Redux 官方文档:github.com/alibaba/fis… ↩