mobx.dart icon indicating copy to clipboard operation
mobx.dart copied to clipboard

debounce / throttle reactions

Open subzero911 opened this issue 3 years ago • 8 comments

As these methods are often used in most apps, I suggest to add them to MobX. This will save us from dealing with rx_dart.

// Called every time the user stops typing
Observable<String> obsText = Observable(textController.text);
debounce(obsText.value, (text) => search(text), time: Duration(milliseconds: 500));

/// Ignore all clicks within 1 second.
ObservableStream buttonClicks;
throttle(buttonClicks.value, (_) => Navigator.push(context, NextPage()), time: Duration(seconds: 1));

They are already present in GetX (but reactions with strange name "workers", and throttle is called "interval"): https://github.com/jonataslaw/getx/blob/master/documentation/en_US/state_management.md#workers I'm not fond of GetX myself, but I found the idea of debounce and throttle reactions convenient.

subzero911 avatar Mar 13 '22 11:03 subzero911

There is a package for stream transformation from dart team. I am using it to throttle streams. https://pub.dev/packages/stream_transform

deadsoul44 avatar Mar 13 '22 11:03 deadsoul44

But this still requires including the side package. And it's for stream transformation, not for working with Observable type.

subzero911 avatar Mar 13 '22 21:03 subzero911

@subzero911

https://mobx.netlify.app/examples/connectivity

reaction((_) => store.connectivityStream.value, (result) {
                final messenger = ScaffoldMessenger.of(context);

                messenger.showSnackBar(SnackBar(
                    content: Text(result == ConnectivityResult.none
                        ? 'You\'re offline'
                        : 'You\'re online')));
              }, delay: 4000);

A reaction is used here as we are only interested in letting users know when the connection state changes. The value passed as the first argument to the reaction function represents reactive state that needs to be tracked i.e. the status of the user's connection. The second argument represents the code that we want executed whenever the reactive state changes.

In this example, we want a snackbar displayed to notify users about updates to their connection status. In areas where connections can repeatedly drop in and out, it may be desirable to avoid showing too many messages that would otherwise degrade the user experience. To solve this problem, the reaction function allows specifying a delay in milliseconds. In this scenario, we have specified a delay of 4000 milliseconds (i.e. 4 seconds). The effect of this is that the snackbar will only be shown if 4 seconds have passed since the status of the user's connection has changed.

amondnet avatar Mar 30 '22 04:03 amondnet

So the delay parameter is actually a debounce? Wow, I didn't know about it.

subzero911 avatar Apr 11 '22 20:04 subzero911

But this still requires including the side package. And it's for stream transformation, not for working with Observable type.

It also works with observables. You will just add .asObservable after stream transformation.

deadsoul44 avatar Apr 11 '22 20:04 deadsoul44

It makes sense to rename delay parameter to debounce, because it actually is.

subzero911 avatar Sep 30 '22 20:09 subzero911