context_watch

Creator: coderz1093

Last updated:

0 purchases

context_watch Image
context_watch Images

Languages

Categories

Add to Cart

Description:

context watch

context_watch #





Subscribe widgets to any observable value using observable.watch(context). No strings attached.
See context_plus for the ultimate convenience.
Features #


.watch(context) - rebuild the context whenever the observable notifies of a change. Returns the current value or AsyncSnapshot for corresponding types.


.watchOnly(context, (...) => ...) - rebuild the context whenever the observable notifies of a change, but only if selected value has changed.


.watchEffect(context, (...) => ...) - execute the provided callback whenever the observable notifies of a change without rebuilding the context.


Multi-value observing of up to 4 observables:
final (value, futureSnap, streamSnap) =
(valueListenable, future, stream).watch(context);
// or in different order
final (streamSnap, value, futureSnap) =
(stream, valueListenable, future).watch(context);
copied to clipboard
All three methods are available for all combinations of observables.
** Note: IDE suggestions for watch*() methods on records work only with Dart 3.6 and newer (see dart-lang/sdk#56572).


Supported observable types #
Built-in #

Listenable (ChangeNotifier/ValueNotifier/AnimationController/ScrollController/TabController etc.):
Stream/ValueStream
Future/SynchronousFuture

Integrations #



Package
Pub
Description




context_watch_bloc

.watch(context).watchOnly(context, () => ...).watchEffect(context, () => ...)for Bloc and Cubit


context_watch_mobx

.watch(context).watchOnly(context, () => ...).watchEffect(context, () => ...)for Observable


context_watch_getx

.watch(context).watchOnly(context, () => ...).watchEffect(context, () => ...)for Rx


context_watch_signals

.watch(context).watchOnly(context, () => ...).watchEffect(context, () => ...)for Signal



Getting started #
flutter pub add context_watch
copied to clipboard
Wrap your app in a ContextWatch.root widget.
ContextWatch.root(
child: MaterialApp(...),
);
copied to clipboard
Usage #
final counterNotifier = ValueNotifier(0);

class Example extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counter = counterNotifier.watch(context);
return Text('Counter: $counter');
}
}
copied to clipboard
That's it! No builders, no custom base classes.
Just call watch() on your observable value and you've got a reactive widget. watch()'ing a ValueListenable,
ValueStream or SynchronousFuture will also give you the current value synchronously, right away.
It doesn't matter where you call watch() from or how many times you call it. While in a build phase, it will
always register the context as a listener to the observable value. Whenever the observable notifies of a change,
the context will be marked as needing a rebuild.
Additional information #
Is conditional watching supported? #
Totally.
You can add or remove watch() calls from the build method as much as you want. The subscriptions are guaranteed to be canceled for all watch() calls that disappeared from the build method as a result of processing the watch()'ed observable value change notification. No extra rebuilds will be triggered.
Worst case scenario is you'll have exactly one additional rebuild upon observable notification if the widget was rebuilt due to anything else than watch()'ed observable notification and ALL watch() calls disappeared during that rebuild.
Performance #
Here's some benchmark results I got on my test device (Xiaomi Mi 9T Pro, Android 11):
Summary Ratio Total subscriptions Subscriptions description Frame times
Stream.watch(context) vs StreamBuilder 1.04x 2 total subs 1 tiles * 2 observables 123.48μs/frame vs 119.18μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.01x 2 total subs 1 tiles * 2 observables 118.25μs/frame vs 117.57μs/frame
Stream.watch(context) vs StreamBuilder 0.99x 20 total subs 10 tiles * 2 observables 117.11μs/frame vs 118.29μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 0.99x 20 total subs 10 tiles * 2 observables 125.07μs/frame vs 126.20μs/frame
Stream.watch(context) vs StreamBuilder 0.97x 200 total subs 100 tiles * 2 observables 124.08μs/frame vs 128.21μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.02x 200 total subs 100 tiles * 2 observables 126.66μs/frame vs 124.19μs/frame
Stream.watch(context) vs StreamBuilder 1.03x 400 total subs 200 tiles * 2 observables 136.98μs/frame vs 132.95μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.03x 400 total subs 200 tiles * 2 observables 133.89μs/frame vs 129.59μs/frame
Stream.watch(context) vs StreamBuilder 1.00x 1000 total subs 500 tiles * 2 observables 156.49μs/frame vs 156.61μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.03x 1000 total subs 500 tiles * 2 observables 160.20μs/frame vs 155.95μs/frame
Stream.watch(context) vs StreamBuilder 1.03x 1500 total subs 750 tiles * 2 observables 202.03μs/frame vs 195.29μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.07x 1500 total subs 750 tiles * 2 observables 177.80μs/frame vs 166.52μs/frame
Stream.watch(context) vs StreamBuilder 1.22x 2000 total subs 1000 tiles * 2 observables 261.17μs/frame vs 214.00μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.29x 2000 total subs 1000 tiles * 2 observables 240.30μs/frame vs 186.12μs/frame
Stream.watch(context) vs StreamBuilder 1.25x 10000 total subs 5000 tiles * 2 observables 50980.63μs/frame vs 40919.80μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.03x 10000 total subs 5000 tiles * 2 observables 24822.21μs/frame vs 24126.57μs/frame
Stream.watch(context) vs StreamBuilder 1.04x 20000 total subs 10000 tiles * 2 observables 167661.58μs/frame vs 161882.15μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.14x 20000 total subs 10000 tiles * 2 observables 99922.14μs/frame vs 87301.35μs/frame
Stream.watch(context) vs StreamBuilder 0.99x 40000 total subs 20000 tiles * 2 observables 293532.14μs/frame vs 295784.43μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.28x 40000 total subs 20000 tiles * 2 observables 222806.22μs/frame vs 173726.25μs/frame
Stream.watch(context) vs StreamBuilder 1.02x 1 total subs 1 single stream subscriptions 123.83μs/frame vs 121.77μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 0.95x 1 total subs 1 single stream subscriptions 119.95μs/frame vs 126.18μs/frame
Stream.watch(context) vs StreamBuilder 0.96x 10 total subs 10 single stream subscriptions 120.39μs/frame vs 124.77μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.01x 10 total subs 10 single stream subscriptions 125.36μs/frame vs 124.10μs/frame
Stream.watch(context) vs StreamBuilder 0.99x 100 total subs 100 single stream subscriptions 122.81μs/frame vs 124.03μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.00x 100 total subs 100 single stream subscriptions 125.93μs/frame vs 126.14μs/frame
Stream.watch(context) vs StreamBuilder 1.00x 200 total subs 200 single stream subscriptions 122.83μs/frame vs 123.00μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.00x 200 total subs 200 single stream subscriptions 125.96μs/frame vs 126.03μs/frame
Stream.watch(context) vs StreamBuilder 1.02x 500 total subs 500 single stream subscriptions 129.61μs/frame vs 127.05μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.04x 500 total subs 500 single stream subscriptions 128.49μs/frame vs 123.32μs/frame
Stream.watch(context) vs StreamBuilder 1.02x 750 total subs 750 single stream subscriptions 132.97μs/frame vs 130.03μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 0.99x 750 total subs 750 single stream subscriptions 127.21μs/frame vs 127.99μs/frame
Stream.watch(context) vs StreamBuilder 1.03x 1000 total subs 1000 single stream subscriptions 139.48μs/frame vs 134.83μs/frame
ValueListenable.watch(context) vs ValueListenableBuilder 1.05x 1000 total subs 1000 single stream subscriptions 133.62μs/frame vs 127.10μs/frame
copied to clipboard
example contains both a live benchmark and an automated one, so feel free to run them and compare the results on your device.
Don't forget to run them in --profile mode.

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Files In This Product:

Customer Reviews

There are no reviews.