Flutter GetX状态管理原理

前言

我们知道Flutter UI框架是声明式的,它也有自己的状态管理机制. 例如StatefulWidget中是State就是Widget中的状态对象. 原本状态的维护方式是这样.

scala 复制代码
class IdentificationCard extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return IdentificationState();
  }
}

class IdentificationState extends State<IdentificationCard> {
  String date = "555";
  String name = "666";

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
                Text('date : $date'),
                Text('name : $name'), 
                GestureDetector(onTap: () {
                  setState(() {
                    date = "777";
                  });
                }, child: const Text('修改'))],
    );
  }
}

UI的状态放在State中,在状态发生改变的时候通过setState方法刷新UI.

这样不是很好区分 展示,业务逻辑,数据之间的代码,感觉很乱. 通过引入GetX插件改造后.

scala 复制代码
/// 状态
class IdentificationState {
  RxString date = "555".obs;
  RxString name = "666".obs;
}

/// 业务逻辑
class IdentificationController extends GetxController {
  IdentificationState state = IdentificationState();
}

/// 展示
class IdentificationCard extends StatelessWidget {
  IdentificationController controller = Get.put(IdentificationController());

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      return Column(
        children: [
          Text('date : ${controller.state.date}'),
          Text('name : ${controller.state.name}'),
          GestureDetector(
              onTap: () {
                controller.state.date.value = "777";
              },
              child: const Text('修改'))
        ],
      );
    });
  }
}

GetX提供的的这套状态管理把展示,业务逻辑,状态的代码分开了,这样看起来就非常的清晰。不过开始用这套框架的时候我觉得很神奇,为啥我加一个Obx就能自动监听状态的改变并且刷新UI了,于是看了下代码了解大概.

Obx如何实现

首先我们来看Obx是个什么

上面我们能够看到出来Obx本质来说是一个StatefulWidget, 并且它也有自己State.

从ObxState中我们能够看到

scss 复制代码
void _updateTree(_) {
  if (mounted) {
    setState(() {});
  }
}

在_updateTree中会调用setState刷新Widget. updateTree的调用是下面listen中调用.

php 复制代码
 _observer.listen(_updateTree, cancelOnError: false);

我们需要关注RxNotifier具体的实现看看神奇发生的地方.

NotifyManager中实现了一个GetStream

而按照GetStream的解释是,它是一个轻量级的事件流,类似于StreamController。

这样一来我们就明白了Obx实际上是一个StatefulWidget,它里面监听了一个GetStream,一旦GetStream有事件通知,它就会进行setState重新进行Widget的构造.

Rx如何实现

那现在我们关注一下Rx对象的的实现。拿RxString举例子

以上三个截图让我们知道了,Rx对象实际上是一个RxNotifier,那么前面我们提到ObxState中也有一个RxNotifier(_observer)它们实际上都共用同一个GetStream.

如果我们在更改Rx值的时候同时向GetStream中发送事件导致Obx这个StatefulWidget重新构建能说得通了。实际我们看代码能够得出就是这么一个路子。

RxObjectMixin中的实现

ini 复制代码
mixin RxObjectMixin<T> on NotifyManager<T> {

    late T _value;

    set value(T val) {
      if (subject.isClosed) return;
      sentToStream = false;
      if (_value == val && !firstRebuild) return;
      firstRebuild = false;
      _value = val;
      sentToStream = true;
      subject.add(_value);
    }
    // 代码省略...
}

我们在给value赋值的时候就是再调用subject.add(_value) 给 GetStream中发送事件,这样一来Obx就能够重新构建了.

总结

这套代码流程看下来后,对GexX的状态管理做一个简单总结,Obx实际一个StatefulWidget,它的State也就是ObxState中监听了GetStream事件流,通过接收GetStream事件流调用setState重新构建Obx,Rx对象在改变value的时候会向GetStream事件流发送事件,这样就会导致Obx进行刷新了.

相关推荐
HokKeung几秒前
Git Hooks 和 Husky 怎么选
前端·前端工程化
李明卫杭州2 分钟前
Vue 3 响应式三剑客:ref、shallowRef、reactive,你真的用对了吗?
前端
触底反弹4 分钟前
🔥 JavaScript this 指向全解析:面试必考的 5 大绑定规则
前端·javascript·面试
Csvn38 分钟前
TypeScript 类型守卫的 4 个实战级别:从 `filter(Boolean)` 到自定义类型谓词
前端
帅次43 分钟前
Android 高级工程师面试:Kotlin 语法基础 近1年高频追问 22 题
android·面试·kotlin·扩展函数·空安全
骑士雄师1 小时前
langchain:推荐切片策略
服务器·前端·langchain
云浪1 小时前
拆开 WAV,看见声音——JavaScript 二进制数组实战全解析
前端·javascript·ecmascript 6
_瑞1 小时前
深入理解灵动岛
前端·ios·app
想你依然心痛1 小时前
嵌入式日志系统:分级日志、环形缓冲区与远程输出——运行时调试、非侵入
android·前端·javascript
这是个栗子2 小时前
【Vue代码分析】 import.meta.env.DEV:现代前端工程中的环境变量
前端·javascript·vue.js·环境变量