GetX 刷新机制研究

在项目中使用了 GetX,我最常用的是 Obx,但是有时 Obx 不会刷新组件,所以对 GetX 中的刷新机制研究一番。

Obx 中的刷新机制

Obx 的刷新依赖于在 build 过程中读取到的 Rx 对象。简单说就是,Obx 里面访问了哪个 .obs 变量,它就会订阅哪个变量的变化。这个变量变化后,Obx 才会重新 build。

最常见的写法:

1
2
3
final count = 0.obs;

Obx(() => Text('${count.value}'));

这种情况下,count.value++ 之后 UI 会刷新。

为什么有时不刷新

比较容易踩坑的是对象内部字段变化。

1
2
final user = User(name: 'A').obs;
user.value.name = 'B';

这种写法只是改了 user.value 里面对象的字段,Rx 对象本身不一定知道变化了,所以 Obx 可能不会刷新。

一般有几种处理方式:

1
user.refresh();

或者直接重新赋值:

1
user.value = User(name: 'B');

如果是列表,尽量使用 RxList 自己的方法,例如 addremoveassignAll,不要只改普通 List 后指望它自动刷新。

GetBuilder 和 Obx 的区别

GetBuilder 是手动刷新,调用 controller 的 update() 才会刷新对应组件。

Obx 是响应式刷新,依赖 Rx 变量的变化。

所以如果是很明确的局部刷新,用 GetBuilder 也挺直接;如果数据本身就是响应式的,用 Obx 写起来更舒服。

小结

目前我的理解是:

  • Obx 只会响应它实际读取到的 Rx 变量。
  • 修改对象内部字段时,最好 refresh() 或重新赋值。
  • 列表优先用 RxList 的方法。
  • 如果就是想手动控制刷新,GetBuilder + update() 更直观。

这篇先记录到这里,后面有时间再继续看 GetX 源码里的依赖收集和通知流程。