当前位置: 首页 > news >正文

Flutter MobX 响应式原理与实战详解

📚 Flutter 状态管理系列文章目录
  1. setState() 使用详解:原理及注意事项

  2. Flutter 状态管理(setState、InheritedWidget、 Provider 、Riverpod、 BLoC / Cubit、 GetX 、MobX 、Redux)

  3. InheritedWidget 组件使用及原理

  4. Flutter 中 Provider 的使用、注意事项与原理解析(含代码实战)

  5. GetX 用法详细解析以及注意事项

  6. Flutter BLoC 使用详细解析

  7. Flutter MobX 响应式原理与实战详解

✨ 起点:为什么要了解 MobX?

作为一个刚开始接触 Flutter 状态管理的开发者,我最初接触到的是 setStateProvider 等方式。当我看到有人说 MobX 是“最像魔法的状态管理库”时,我开始好奇:为什么它能不写 setState 就自动刷新 UI?

带着这样的疑问,我开启了对 MobX 的深入探索。这篇文章就是我把所有探索过程系统整理后的总结,希望对你也有帮助。


🛠 一、MobX 的安装与基本使用

MobX 的核心有三大类:

概念说明
Observable可观察状态,类似变量。变化时自动触发 UI 更新
Action改变状态的行为,所有状态变更建议通过 action
Reaction监听变化后做副作用,比如打印日志、导航等

1. 添加依赖

pubspec.yaml 中:

dependencies:flutter:sdk: fluttermobx: ^2.2.0flutter_mobx: ^2.0.6dev_dependencies:build_runner: ^2.4.6mobx_codegen: ^2.4.0

2.创建一个 MobX Store(状态容器)

counter_store.dart

import 'package:mobx/mobx.dart';part 'counter_store.g.dart'; // 自动生成的文件class CounterStore = _CounterStore with _$CounterStore;abstract class _CounterStore with Store {int count = 0;void increment() {count++;}
}

生成代码命令:

flutter pub run build_runner build
# 或者自动监听:
flutter pub run build_runner watch

3. 使用 Observer 监听状态

import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'counter_store.dart';class CounterPage extends StatelessWidget {final CounterStore counter = CounterStore();Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("MobX Counter")),body: Center(child: Observer(builder: (_) => Text('${counter.count}',style: TextStyle(fontSize: 40),),),),floatingActionButton: FloatingActionButton(onPressed: counter.increment,child: Icon(Icons.add),),);}
}

📚 二、MobX 核心注解说明

注解作用示例
@observable可监听变量@observable int count = 0;
@action状态改变函数@action void increment() => count++;
@computed派生状态String get fullName => "$firstName $lastName";

🧩 三、不同类型的 Observer 使用方式

类型使用场景是否支持 child是否自动跟踪依赖
Observer通用 UI 刷新
Observer.builder自定义构建器
ObserverWidget(自定义)可封装为组件
Observer + child:子组件不依赖状态,可优化性能

1️⃣ 最常用的 Observer

适用于所有直接在 build() 方法中监听 observable 状态的场景。

✅ 示例:
Observer(builder: (_) => Text('${counter.count}',style: TextStyle(fontSize: 32),),
)

每当 counter.count 更新时,Text 会自动重建。


2️⃣ Observer + child 优化重建

用于优化性能:当 UI 中部分元素是静态的,可以通过 child 参数避免重建。

✅ 示例:
Observer(child: Icon(Icons.favorite), // 不会因为状态变化而重建builder: (_, child) => Row(mainAxisAlignment: MainAxisAlignment.center,children: [child!,SizedBox(width: 8),Text('${counter.count}'),],),
)

Icon 是静态内容,MobX 不会重复创建,节省性能。


3️⃣ 封装成组件:自定义 ObserverWidget

当你想将 Observer 封装成复用组件时,可创建一个继承自 StatelessWidgetObserver 控件。

✅ 示例:
class CountText extends StatelessWidget {final CounterStore store;const CountText({required this.store});Widget build(BuildContext context) {return Observer(builder: (_) => Text('${store.count}', style: TextStyle(fontSize: 24)),);}
}

使用方式:

CountText(store: counterStore)

4️⃣ ListView/GridView 中的 Observer

当你需要对列表内容做响应式刷新时,每个 item 可以使用 Observer 包裹。

✅ 示例:
Observer(builder: (_) => ListView.builder(itemCount: todoStore.todos.length,itemBuilder: (_, index) {final todo = todoStore.todos[index];return Observer(builder: (_) => CheckboxListTile(value: todo.done,onChanged: (_) => todo.toggleDone(),title: Text(todo.title),),);},),
)

每个 CheckboxListTile 都会监听自己对应的 todo.done,提高效率。


🧠 补充:多层 Observer 嵌套性能说明

MobX 的响应式追踪是“精确依赖感知”的,每个 Observer 只监听自己用到的 @observable不会因为 store 中其他字段变化而重建,比传统 Provider 更细粒度。


✅ 小结对比
类型优势适用场景
Observer最常用,自动追踪通用响应式 UI
Observer + child性能优化静态元素嵌入 UI
自定义 StatelessWidget 包裹 Observer组件复用通用响应式组件
列表中嵌套 Observer精细追踪每一项变化todo、商品列表

✅ MobX 为什么可以“这么做”——原理解析

一、核心机制:可观察(Observable) + 自动追踪(Tracking)
  1. @observable 的变量不是普通变量,而是被 MobX 包装成了 可追踪对象(Atom)

  2. Observer 被构建时,MobX 开启一个 “追踪上下文”(Tracking Context):

    • Observer.builder() 中访问了哪些 @observable,就自动把这些变量注册为“依赖”。
  3. 一旦这些依赖发生变化,MobX 会自动通知 Observer 重新构建 UI。


二、过程举例说明

int count = 0;Observer(builder: (_) => Text('$count'),
)

➡ MobX 做了什么?

  1. 初次 build 时读取了 count,MobX 会记录下这个“读取动作”:

    “这个 Observer 正在依赖 count!”

  2. 后续调用 count++(即修改 observable)时:

    • MobX 发现 count 改了,它就通知所有依赖 count 的观察者(也就是这个 Observer)重新执行 builder,从而刷新 UI。

三、MobX 响应式模型的类比

可以把 MobX 的响应式系统类比成:

  • @observable = 数据源(比如“温度传感器”)
  • Observer = 显示模块(比如“电子温度计”)
  • MobX = 自动布线系统,知道哪个显示器监听哪个传感器

只要传感器变化,显示模块就刷新。开发者什么都不用手动做。


四、底层依赖追踪的原理:Atom + Reaction

MobX 的核心类是:

说明
Atom每个 observable 变量都是一个 Atom
Reaction每个 Observer 内部注册了一个 reaction
Context每次执行 builder() 时,MobX 开启上下文收集依赖
Derivation指的是任何依赖 observable 的函数,比如 computedObserver

五、Flutter 中 UI 为什么可以重建?

因为 Observer 继承自 StatelessWidget,而其内部逻辑其实是这样的(伪代码):

class Observer extends StatelessWidget {final Reaction _reaction;Observer({required WidgetBuilder builder}) {_reaction = Reaction(() {// 当依赖的 observable 改变时,调用 setState 或 rebuild});}Widget build(BuildContext context) {// 启动依赖收集_reaction.track(() {builder(context); // 在这个过程中读取 observable,就会注册依赖});}
}

✅ 总结一句话

MobX 可以“这么做”,是因为它在 Observer.builder 执行时自动收集依赖变量,一旦这些变量变化,MobX 会主动通知刷新 UI。你不需要写 setState,它已经帮你自动“追踪 + 通知 + 重建”了。


⚙️ 五、自己手写一个简化版 MobX(低配实现)

太棒了!下面我就来写一个低配版的 MobX 响应式系统实现,让你直观理解它的底层机制。这个版本包括:

  1. Observable<T>:可观察变量
  2. Reaction:监听依赖并自动响应
  3. autorun():一个简化版的 Observer 行为
  4. 自动依赖追踪:MobX 的“神操作”

🧠 目标:当你读取 observable 的时候自动注册依赖,当你修改 observable 的时候,能触发依赖函数。


🔧 第一步:实现全局上下文收集机制

typedef VoidCallback = void Function();class ReactiveContext {static final ReactiveContext _instance = ReactiveContext._internal();VoidCallback? _currentReaction;factory ReactiveContext() => _instance;ReactiveContext._internal();void setCurrentReaction(VoidCallback? reaction) {_currentReaction = reaction;}VoidCallback? get currentReaction => _currentReaction;
}

🔮 第二步:实现 Observable

class Observable<T> {T _value;final Set<VoidCallback> _listeners = {};Observable(this._value);T get value {// 自动依赖收集final reaction = ReactiveContext()._currentReaction;if (reaction != null) {_listeners.add(reaction);}return _value;}set value(T newValue) {if (newValue != _value) {_value = newValue;// 通知所有监听者for (var listener in _listeners) {listener();}}}
}

🔁 第三步:实现 autorun(模拟 Observer)

void autorun(VoidCallback runner) {void wrapped() {ReactiveContext().setCurrentReaction(wrapped); // 注册当前 reactionrunner();ReactiveContext().setCurrentReaction(null); // 清理}wrapped(); // 初始执行一次,收集依赖
}

🎯 示例:模拟 Counter 自动追踪 + 响应

void main() {final count = Observable(0);autorun(() {print("当前 count 是:${count.value}");});// 模拟用户操作count.value = 1; // 自动触发 autorun 输出count.value = 2;
}
✅ 输出:
当前 count 是:0
当前 count 是:1
当前 count 是:2

🧠 总结:

MobX 组件我们实现的类
@observableObservable<T>
Observerautorun()
依赖追踪ReactiveContext
reactionVoidCallback 注册

💡 提升建议:

你可以进一步加上:

  • computed(派生值)
  • action(封装状态更新)
  • dispose()(清除监听)
  • 与 Flutter Widget 结合(如用 ValueListenableBuilder 或自写 ObserverWidget

🗺 六、MobX 响应流程图

Observable↓ (读取)
Reaction ← 自动注册依赖↓
值变化?↓ 是
刷新 UI(Observer)

(你也可以参考文中附图,完整展现了 MobX 的响应链条)


✅ 七、总结:MobX 值得用吗?

MobX 让状态管理变得优雅和现代化:

  • 不用写 setState
  • 不需要 notifyListeners
  • 自动依赖收集
  • 最细粒度响应更新

适合追求响应式编程和简洁架构的开发者。如果你喜欢 Vue、Svelte 那种“写了就动”的感觉,MobX 会让你爱不释手。


🧰 附加建议

  • 推荐将每个 Store 模块化、组件化;
  • 可结合依赖注入工具如 GetIt 使用;
  • 想要更复杂管理?可引入 reactionwhen 进行副作用管理。
📚 Flutter 状态管理系列文章目录
  1. setState() 使用详解:原理及注意事项

  2. Flutter 状态管理(setState、InheritedWidget、 Provider 、Riverpod、 BLoC / Cubit、 GetX 、MobX 、Redux)

  3. InheritedWidget 组件使用及原理

  4. Flutter 中 Provider 的使用、注意事项与原理解析(含代码实战)

  5. GetX 用法详细解析以及注意事项

  6. Flutter BLoC 使用详细解析

  7. Flutter MobX 响应式原理与实战详解

相关文章:

  • 建筑通seo关键词优化排名外包
  • 做网站背景的图杭州seo网站排名
  • 微信小程序电脑端打开黑帽seo联系方式
  • 做网站方面的问题深圳全网推广公司
  • 免费的个人简历ppt模板百度seo刷排名工具
  • 怎么建企业自己的网站吗ip营销的概念
  • cocos2 本地根据文本内容生成二维码
  • Docker安装Arroyo流处理引擎
  • Deepin Linux如何安装Terminus终端教程
  • RAG入门课程-学习笔记
  • 矩阵题解——螺旋矩阵【LeetCode】
  • Class00.2线性代数
  • rules写成动态
  • 解决npm安装依赖报错ERESOLVE unable to resolve dependency tree
  • excel中vba开发工具
  • C语言基础回顾与Objective-C核心类型详解
  • 15个AI模拟面试平台 和 简历修改 / 真人面试平台
  • 【服务器】服务器选型设计
  • windows 怎么下载yarn安装包并将下载的yarn文件移动到全局目录并添加执行权限?
  • 防火墙快速管理软件,66K超小巧
  • 数据文件写入技术详解:从CSV到Excel的ETL流程优化
  • 批量删除 word文档里面多个相同表格的特定行
  • 博图SCL语言中 RETURN 语句使用详解
  • 【项目】仿muduo库one thread one loop式并发服务器HTTP协议模块
  • 新能源知识库(67)高温热泵在电镀领域的应用
  • LVS-NAT负载均衡群集实战:原理、部署与问题排查