新闻详情

新闻详情

首页 / 资讯中心 / 详情

fish_redux 生命周期机制全解析:Component 与 Adapter 的三层生命周期模型及 appear/disappear 扩展

发布时间:2026/9/29 6:07:19来源:尧图网络
fish_redux 生命周期机制全解析:Component 与 Adapter 的三层生命周期模型及 appear/disappear 扩展
前端【免费下载链接】fish-reduxAn assembled flutter application framework.项目地址https://gitcode.com/gh_mirrors/fi/fish-redux点击查看免费下载导读本文以 doc/concept/lifecycle.md 为骨架深入 fish_redux 的生命周期机制——它本质上完全复用 FlutterStateStatefulWidget的六阶段生命周期但在 Component 与 Adapter 中呈现出截然不同的三层Reducer / Effect / View生命周期模型并额外引入appear/disappear与didChangeAppLifecycleState两个扩展事件。读完本文你将掌握生命周期事件在页面、组件、列表适配器中的传播路径与触发时机并能在自己的 Effect 中准确捕获initState、dispose、appear、disappear等 Action写出不依赖视图存活时间的可靠业务逻辑。一、总览一切生命周期都源自 Flutter Statefish_redux 的生命周期设计有一个非常明确的出发点默认的所有生命周期本质上都来自于 FlutterStateStatefulWidget中的生命周期。也就是说框架并没有自创一套与 Flutter 割裂的生命周期体系而是把 Flutter 已经验证过的State生命周期事件统一映射为Lifecycle枚举再通过dispatch以 Action 的形式下发给 Reducer 与 Effect。FlutterState的原生生命周期如下见 lib/src/redux_component/component.dart 中ComponentState对它们的逐一承接initStateState 首次挂载到树中时触发didChangeDependencies依赖的 InheritedWidget 发生变化时触发build构建 Widget 时触发didUpdateWidget父 Widget 重建导致当前 Widget 配置更新时触发deactivateWidget 从树中移除如列表项划出可视区时触发disposeState 被彻底销毁时触发。在 fish_redux 中这些事件不再是黑盒回调而是被框架统一转换为Action其中Lifecycle枚举定义于 lib/src/redux_component/lifecycle.dartenum Lifecycle { initState, didChangeDependencies, build, reassemble, didUpdateWidget, deactivate, dispose, appear, // 仅混入 VisibleChangeMixin 的 Adapter 会收到 disappear, // 仅混入 VisibleChangeMixin 的 Adapter 会收到 didChangeAppLifecycleState, // 仅混入 WidgetsBindingObserverMixin 的组件会收到 }对应的 Action 构造器集中在同文件下的LifecycleCreator中lib/src/redux_component/lifecycle.dart例如static Action initState() const Action(Lifecycle.initState); static Action build(String name) Action(Lifecycle.build, payload: name); static Action appear(int index) Action(Lifecycle.appear, payload: index); static Action disappear(int index) Action(Lifecycle.disappear, payload: index);注意appear/disappear的 payload 是列表项的indexdidChangeAppLifecycleState的 payload 则是 Flutter 的AppLifecycleStateresumed、inactive、paused、detached等这些 payload 可以在 Effect 中直接读取从而获得事件发生的上下文信息。二、事件分发链路Lifecycle Action 如何到达 Reducer 与 Effect生命周期事件本身只是信号真正让它们产生业务效果的是分发链路。从 lib/src/redux_component/context.dart 可以看到每个LogicContext都持有onLifecycle入口它把 Lifecycle Action 送入标准的 dispatch 管道override void onLifecycle(Action action) { assert(_throwIfDisposed()); _dispatch(action); }随后 Action 会沿Effect - Reducer - View的方向依次经过框架的中间件middleware处理。这就是为什么生命周期事件在 Effect 里可以被监听、在 Reducer 里可以被处理——它们只是一种特殊的 Action 类型而已。例如在 test/lib/redux_component/lifecycle_test.dart 中测试代码就是通过在 Effect 中拦截Lifecycle.initState、Lifecycle.build、Lifecycle.dispose等 Action 来记录生命周期轨迹的effect: instrumentEffectTodo(toDoEffect, (Action action, GetTodo getState) { if (action.type Lifecycle.initState) { track.append(toDo-initState); } else if (action.type Lifecycle.build) { track.append(toDo-build); } else if (action.type Lifecycle.didChangeDependencies) { track.append(toDo-didChangeDependencies); } else if (action.type Lifecycle.didUpdateWidget) { track.append(toDo-didUpdateWidget); } else if (action.type Lifecycle.dispose) { track.append(toDo-dispose); } }),该测试随后用Track.pins精确断言了组件的完整生命周期顺序test/lib/redux_component/lifecycle_test.darttoDo-initState → toDo-didChangeDependencies → toDo-build → toDo-onEdit → toDo-didUpdateWidget → toDo-build → toDo-deactivate → toDo-dispose这一顺序与 FlutterState的实际触发顺序完全一致印证了文档默认生命周期源自 Flutter State的说法。三、Component 内的三层生命周期模型Reducer 与页面同寿Effect/View 与 Widget 同寿原文档给出的第二个核心论断是在组件内Reducer 的生命周期是和页面一致的Effect 和 View 的生命周期是和组件的 Widget 一致的。理解这句话需要先明确 fish_redux 的分层一个 Component 由View Effect(可选) Reducer(可选) Dependencies(可选)组成见 doc/concept/component.md其中Reducer 的存活周期 Page/Store 的存活周期。Reducer 是纯函数它不依赖任何 Widget只依赖 Store 中的 state。只要页面Page的 Store 没有被销毁Reducer 就一直在为状态兜底。在 lib/src/redux_component/page.dart 中可以看到_PageState.initState创建Store_PageState.dispose中执行_store.teardown()——Store 的生死与页面 State 绑定而所有组件共享这个 Store因此无论子组件的 Widget 如何重建、销毁只要页面存活Reducer 就能持续处理来自任何来源的 Action。Effect 与 View 的存活周期 组件对应 Widget 的存活周期。Effect 负责副作用网络、计时、事件监听View 负责渲染它们都依附于ComponentWidget这个StatefulWidget。当 Widget 被销毁时Effect 也一并消失。这条链路在ComponentStatelib/src/redux_component/component.dart中体现得十分完整override void initState() { super.initState(); _ctx widget.component.createContext(...); // 创建上下文 _ctx.registerOnDisposed(widget.store.subscribe(() _ctx.onNotify())); _ctx.onLifecycle(LifecycleCreator.initState()); // 派发 initState } override void didChangeDependencies() { super.didChangeDependencies(); if (widget.component.protectedClearOnDependenciesChanged ! false) { _ctx.clearCache(); } _ctx.onLifecycle(LifecycleCreator.didChangeDependencies()); } override Widget build(BuildContext context) _ctx.buildWidget(); // 内部派发 build override void deactivate() { super.deactivate(); _ctx.onLifecycle(LifecycleCreator.deactivate()); } override void didUpdateWidget(ComponentWidgetT oldWidget) { super.didUpdateWidget(oldWidget); _ctx.didUpdateWidget(); _ctx.onLifecycle(LifecycleCreator.didUpdateWidget()); } override void dispose() { if (!_ctx.isDisposed) { _ctx..onLifecycle(LifecycleCreator.dispose())..dispose(); } super.dispose(); }几个值得注意的实现细节build事件携带组件名LifecycleCreator.build(String name)的 payload 是组件名默认为runtimeType.toString()见 lib/src/redux_component/component.dart方便在调试日志中区分是哪个组件在构建。build事件只派发一次在 lib/src/redux_component/context.dart 中buildWidget()通过_widgetCache缓存 Widget只有当缓存为空时才重新调用view(state, dispatch, this)并派发Lifecycle.build。后续的 setState 刷新走的是onNotify/markNeedsBuild不会重复派发build因此 Effect 中不会收到密集的 build 噪音。didChangeDependencies与clearOnDependenciesChanged默认情况下依赖变化时会先clearCache()再派发didChangeDependencies促使 View 重新构建若在Component构造时传入clearOnDependenciesChanged: true可以改变这一行为。四、Adapter 中的生命周期Reducer 长命、Effect 中命、View 短命原文档对 Adapter 场景给出了更加精细的表述在适配器中Reducer 的生命周期是和页面一致的。Effect 的生命周期是和 ListView 的生命周期一致的。View 的生命周期是短暂的划入不可见区域即销毁。这套三段论与 doc/concept/adapter.md 中Reducer is long-lived, Effect is medium-lived, View is short-lived的表述一一对应是 fish_redux 解决 ListView 场景三大痛点大 Cell 无性能优化、无法区分 appear/disappear 与 init/dispose、Effect 与 View 生命周期耦合的核心手段Reducer 长命与页面 Store 绑定列表数据在项 Widget 被销毁后依然保存在 state 中Effect 中命与 ListView即整个列表容器同寿而不是与单个列表项 Widget 同寿。这正是文档强调的Effect-Lifecycle-PromoteEffect 生命周期提升——即使某个列表项还没出现在屏幕上其他模块依然可以通过 dispatch-api 调用它的能力业务逻辑与视图存活彻底解耦View 短命列表项划出可视区即销毁由 Flutter 的列表懒加载机制保证内存与帧率。这一机制在RecycleContextlib/src/redux_adapter/recycle_context.dart中有完整的代码级支撑。Adapter 使用对象池 复用策略管理列表项上下文ContextSysObject reuseOrCreate(Object key, GetContextSysObject create) { final int length _usedIndexMap[key] (_usedIndexMap[key] ?? 0) 1; final ListContextSysObject list _cachedMap[key] ?? ContextSysObject[]; if (length list.length) { _cachedMap[key].add( create()..setParent(this)..onLifecycle(LifecycleCreator.initState()), ); } return list[length - 1]; }新建上下文时才派发initState列表项首次被创建首次进入可视区时触发一次onLifecycle会向所有子上下文广播RecycleContext.onLifecycle先把事件转发给缓存中每个子ContextSys再调用super.onLifecycle(action)lib/src/redux_adapter/recycle_context.dart因此页面级的生命周期会同步传递给列表项回收时派发disposecleanUnused()会找出本轮未被使用的多余上下文依次onLifecycle(LifecycleCreator.dispose())后dispose()并从缓存中移除lib/src/redux_adapter/recycle_context.dart。RecycleContextMixin被StaticFlowAdapter与DynamicFlowAdapter混入使用见 lib/src/redux_adapter/static_flow_adapter.dart 与 lib/src/redux_adapter/dynamic_flow_adapter.dart从源码结构可以推断这套缓存复用 按需 initState/dispose的机制是两种 FlowAdapter 共用的事实基础。五、appear / disappear进入与完全离开显示区的精确回调原文档指出 Adapter 相比普通组件新增了两个生命周期同时增加了 appear 和 disappear 的生命周期代表这个 adapter 管理的视图数组刚进入显示区和完全离开显示区的回调。这是 Adapter 模型区别于 Component 模型的关键能力Component 只有initState/dispose对应 State 的创建与销毁而 Adapter 场景需要区分视图被创建与视图进入用户视野这两个概念。为此框架提供了VisibleChangeMixinlib/src/redux_component_mixin/visible_change_mixin.dart用法如下class MyAdapter extends AdapterT with VisibleChangeMixinT { MyAdapter() : super(/* ... */); }其实现思路是为每个列表项再包一层_VisibleChangeWidget一个StatefulWidget在它的initState与dispose中分别派发appear与disappearlib/src/redux_component_mixin/visible_change_mixin.dartclass _VisibleChangeState extends State_VisibleChangeWidget { override Widget build(BuildContext context) widget.itemBuilder(context, widget.index); override void initState() { super.initState(); widget.dispatch(LifecycleCreator.appear(widget.index)); } override void dispose() { widget.dispatch(LifecycleCreator.disappear(widget.index)); super.dispose(); } }更精巧的是_VisibleChangeDispatchlib/src/redux_component_mixin/visible_change_mixin.dart它内部维护_appearsCount计数器只有当列表项从 0 变成 1第一个进入显示区时才真正派发appear当计数从 1 变成 0最后一个完全离开显示区时才派发disappearvoid onAction(Action action) { if (action.type Lifecycle.appear) { if (_appearsCount 0) { if (!isDisposed) dispatch(action); } _appearsCount; } else if (action.type Lifecycle.disappear) { _appearsCount--; if (_appearsCount 0) { if (!isDisposed) dispatch(action); } } }由此appear/disappear的语义被精确化为视图数组刚进入显示区与完全离开显示区的整体状态变化而非单个列表项的创建/销毁。这与原文档的表述完全吻合也让开发者可以放心地在disappear中执行暂停播放、取消曝光统计等离开视野类逻辑——它绝不会在快速滚动的中间态被误触发。六、两个可选扩展事件reassemble 与 didChangeAppLifecycleState除上述事件外Lifecycle枚举还包含两个需要特定条件才能接收的扩展事件6.1 reassemble热重载reassemble对应 Flutter 的State.reassemble在热重载Hot Reload场景下触发。ComponentState中的实现是lib/src/redux_component/component.dartoverride void reassemble() { super.reassemble(); _ctx.clearCache(); _ctx.onLifecycle(LifecycleCreator.reassemble()); }它先清空 Widget 缓存强制重新走view构建再派发reassemble事件方便开发期刷新副作用状态。6.2 didChangeAppLifecycleState应用前后台切换当需要感知 App 进入后台/回到前台时可以在 Component 或 Page 上混入WidgetsBindingObserverMixinlib/src/redux_component_mixin/widgets_binding_observer_mixin.dartclass MyComponent extends ComponentT with WidgetsBindingObserverMixinT { MyComponent() : super(/* ... */); }其原理是让ComponentState混入 Flutter 的WidgetsBindingObserver在initState中WidgetsBinding.instance.addObserver(this)、在dispose中removeObserver(this)并在didChangeAppLifecycleState回调里把事件转为 Lifecycle Action 派发lib/src/redux_component_mixin/widgets_binding_observer_mixin.dartoverride void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); ctx.onLifecycle(LifecycleCreator.didChangeAppLifecycleState(state)); }Effect 中即可通过action.payload拿到AppLifecycleState实现切后台暂停、回前台恢复这类业务。七、实战建议按生命周期分层放置业务逻辑结合上面的机制可以总结出以下可直接落地的分层实践业务类型推荐放置位置原因页面级状态初始化/清理Reducer 处理initState/disposeReducer 与页面同寿不受 Widget 重建影响列表项的曝光统计、离开视野暂停Effect 处理appear/disappear语义精确首个进入/最后一个离开才触发网络请求、计时器、事件订阅Effect 处理initState启动/dispose释放与组件 Widget 同寿随 Widget 销毁自动清理前后台切换处理Effect 处理didChangeAppLifecycleState需组件混入WidgetsBindingObserverMixin开发期状态刷新Effect 处理reassemble仅在热重载时触发其中关于 Effect 中的订阅与销毁还可以结合 lib/src/redux_component/auto_dispose.dart 的AutoDispose机制——Effect 生命周期结束时框架会统一释放注册的资源避免手动清理遗漏。八、小结fish_redux 的生命周期模型可以概括为一句话生命周期是 FlutterState生命周期的 Action 化映射并按 Component / Adapter 两种模型做了差异化裁剪——Component 场景下 Reducer 与页面同寿、Effect/View 与 Widget 同寿Adapter 场景下进一步演化为Reducer 长命、Effect 中命、View 短命并借助VisibleChangeMixin增加appear/disappear来精确表达显示区进出语义。这套设计的最终目的是让业务逻辑Effect/Reducer与视图存活状态解耦在 ListView 这类高频重建场景下依然稳定可靠。相关机制的完整实现可从 lib/src/redux_component/lifecycle.dart、lib/src/redux_component/component.dart、lib/src/redux_adapter/recycle_context.dart 以及测试用例 test/lib/redux_component/lifecycle_test.dart 中继续深入阅读。赞分享前端【免费下载链接】fish-reduxAn assembled flutter application framework.项目地址https://gitcode.com/gh_mirrors/fi/fish-redux点击查看免费下载相关推荐Yii 2 组件Component机制全解属性、事件与行为三大特性及对象生命周期Yii 2 组件Component机制全解属性、事件与行为三大特性及对象生命周期 Yii 2 的整个框架都构建在「组件」这一基石之上——无论是 Appli后端Web框架Rust 生命周期实践深入理解 static 生命周期Rust 生命周期实践深入理解 static 生命周期 什么是 static 生命周期 在 Rust 中 static 是一个特殊的生命周期标记表示文档教程示例工程Celery信号机制深度解析任务全生命周期的监控与扩展Celery信号机制深度解析任务全生命周期的监控与扩展 信号机制概述 Celery的信号系统是其架构中一个强大而灵活的特性它基于观察者模式实现允许开发者在任务调度后端消息队列上一篇PyInstaller还原源码终极指南pyinstxtractor一键提取exe中的全部pyc字节码下一篇不用虚拟机macOS 也能运行 Windows 应用Whisky 六步实测带你把软件装进 Mac创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

电热综合能源系统日前经济调度:从CHP耦合建模到可再生能源消纳的Matlab实现 2026/9/29 7:55:54

电热综合能源系统日前经济调度:从CHP耦合建模到可再生能源消纳的Matlab实现

1. 问题背景与模型核心思路1.1 为什么要研究电热综合能源系统的日前调度做电力系统优化调度的同行应该都有体会,传统的经济调度模型基本是围绕纯电力系统展开的——机组组合、备用安排、潮流约束,这些内容在各类教材和论文里已经很成熟。但最近几年&…

阅读更多 →
Claude Code与Codex分工实战:AI说完成不等于代码可以提交 2026/9/29 7:55:54

Claude Code与Codex分工实战:AI说完成不等于代码可以提交

最近我的终端里同时跑着 Claude Code 和 Codex。用了一段时间之后,我发现两个问题必须拿出来聊聊:这两个工具到底怎么分工?以及一个更隐蔽的坑——AI agent 在对话框里打出“任务已完成”之后,很多人顺手就把代码 push 上去了&…

阅读更多 →
Windows下Ubuntu 20.04/18.04三系统安装与GRUB实战 2026/9/29 7:55:54

Windows下Ubuntu 20.04/18.04三系统安装与GRUB实战

Ubuntu 20.04 和 18.04 这两个版本放在同一台 Windows 机器上,听起来像是折腾,但在实际工作里这种需求一点都不少见。有人是为了跑 ROS Noetic(20.04 是官方主推)同时又要兼容某个只在 18.04 上编译通过的老项目;有人是…

阅读更多 →
Postman响应面板详解:从状态码到Tests断言,高效排查接口问题 2026/9/29 7:55:54

Postman响应面板详解:从状态码到Tests断言,高效排查接口问题

1. 响应面板整体布局:拿到一次请求结果后先看哪里如果你已经把 Postman 系列从头跟到这里,大概率已经会用 Postman 发 GET、POST 请求,也会配置 Header、Body、Params 了。但很多人在发出请求之后,盯着右侧的响应区一脸懵——信息…

阅读更多 →
计算机网络基础IP地址PPT课件:从二进制到子网划分的完整讲解路径 2026/9/29 7:55:47

计算机网络基础IP地址PPT课件:从二进制到子网划分的完整讲解路径

简介:这份PPT课件面向计算机网络入门学习者与课堂教学场景,系统梳理IP地址相关知识,帮助读者建立从地址结构到子网划分的完整认知。课件共14页,围绕点分十进制与二进制互转、IP地址的Network ID与Host ID组成、A至E五类地址划分、…

阅读更多 →
基于Springboot的二手车交易网站的设计与实现 2026/9/29 7:55:47

基于Springboot的二手车交易网站的设计与实现

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 1. 项目背景与意义 随着汽车保有量的持续增长和消费观念的转变,二手车交易市场呈现出快速发展的态势。传统的线下二手车交易存在信息不对称、车源分散、交易…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉