CustomRef<T> class

A custom ref that allows manual control of tracking and triggering.

Similar to Vue's customRef, this creates a ref where you have full control over when dependencies are tracked and when updates are triggered.

Unlike regular Ref or ComputedRef, customRef gives you manual control via track() and trigger() callbacks:

  • track(): Called in the getter to establish reactive dependencies
  • trigger(): Called in the setter to notify dependent computations

This is useful for:

  • Wrapping external state systems (like Listenable) in reactivity
  • Debouncing or throttling updates
  • Custom validation or transformation logic

Implements WritableRef to provide a consistent interface with other writable reactive references.

Example - Wrapping a Listenable:

CustomRef<ScrollController> useScrollController() {
  final controller = ScrollController();

  final custom = customRef<ScrollController>(
    getter: (track) {
      track(); // Establish dependency
      return controller;
    },
    setter: (value, trigger) {
      // Not used for controllers
    },
  );

  void listener() {
    custom.trigger(); // Notify when controller changes
  }

  controller.addListener(listener);
  onUnmounted(() {
    controller.removeListener(listener);
    controller.dispose();
  });

  return custom;
}

Example - Debounced ref:

CustomRef<String> debouncedRef(String initial, Duration delay) {
  var internalValue = initial;
  Timer? timer;

  return customRef<String>(
    getter: (track) {
      track();
      return internalValue;
    },
    setter: (value, trigger) {
      internalValue = value;
      timer?.cancel();
      timer = Timer(delay, () {
        trigger(); // Only trigger after delay
      });
    },
  );
}
Implemented types

Constructors

CustomRef({required T getter(void track()), required void setter(T value, void trigger())})
Creates a custom ref with manual track/trigger control.

Properties

hashCode int
The hash code for this object.
no setterinherited
raw → T
Gets the raw value without establishing a reactive dependency.
no setteroverride
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
value ↔ T
Gets the current value. Reading this establishes a reactive dependency on the version counter, which is incremented when trigger is called.
getter/setter pairoverride

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() String
A string representation of this object.
inherited
trigger() → void
Manually triggers reactivity without setting a new value.

Operators

operator ==(Object other) bool
The equality operator.
inherited