Bidev
AdvancedState Management

How does GetX's Obx widget know when to rebuild?

Short Answer

Obx subscribes to any .obs observable read inside its builder function during the build — it tracks reads via a global tracking mechanism, rather than requiring you to explicitly declare which values it depends on.

Unlike Provider's Consumer<T> (explicitly typed to one provider) or Riverpod's ref.watch() (explicitly registers a dependency per call), GetX's Obx(() => Text('\${counter.value}')) figures out its dependencies implicitly: when the builder function runs, reading .value on any Rx/.obs variable registers that observable with the currently-building Obx instance, similar in spirit to how MobX or Vue's reactivity system works.

In practice, this means Obx only rebuilds when an observable it actually read last time changes — but it can't detect a dependency it didn't read on the previous build (e.g. a value only read inside a conditional branch that wasn't taken), a subtle source of 'why didn't this rebuild' bugs.

Common Mistakes

  • ×Reading an observable conditionally inside Obx, then being surprised the widget doesn't rebuild when that branch wasn't taken during the last build.
  • ×Nesting Obx widgets unnecessarily instead of one Obx wrapping the whole reactive section.