mobx.dart
mobx.dart copied to clipboard
Proper way of turning an action into separate methods?
Hey! Just want to first say that I'm really grateful for this package the work that went into it.
In the example shown below
import 'package:mobx/mobx.dart';
part 'counter.g.dart';
class Counter = CounterBase with _$Counter;
abstract class CounterBase with Store {
@observable
int value = 0;
@action
void setValue(int value) {
print('Do stuff');
__setValue(value);
}
@action
void __setValue(int value) {
this.value = value;
}
}
Should the the @action annotation be above setValue, __setValue, or both?
Meaning, does the @action only go above the method actually changing the observable? Or the one being called from the flutter ui?
Thanks!
@DanMossa
import 'package:mobx/mobx.dart';
part 'counter.g.dart';
class Counter = CounterBase with _$Counter;
abstract class CounterBase with Store {
@observable
int value = 0;
@action
void setValue(int value) {
print('Do stuff');
this.value = value;
}
}
https://mobx.netlify.app/api/action/
Actions are functions that encapsulate the mutations on observables. They are used to give a semantic name to the operation, such as incrementCounter() instead of simply doing counter++. These semantic names are how you would identify the various operations happening in the domain, as exposed on the UI.
Additionally, actions also provide few other guarantees:
- Changes to the observables are only notified at the end of the action. This ensures all mutations happen as an atomic unit. This also eliminates noisy notifications, especially if you are changing a lot of observables (say, in a loop).
- Actions can call other actions. For such nested actions, the change-notifications will be sent when the top-most action completes.
- All the linked reactions (ones that depend on the observables mutated inside the action) are run only at the end of the action. This also ensures there are no pre-mature reactions occurring in the system.
import 'package:mobx/mobx.dart';
part 'counter.g.dart';
class Counter = CounterBase with _$Counter;
abstract class CounterBase with Store {
@observable
int value = 0;
@action
void setValue(int value) {
print('Do stuff');
this.value = 1;
this.value = 2;
this.value = value;
// notify [value]
}
void setValueWithoutAction(int value) {
print('Do stuff');
this.value = 1;
this.value = 2;
this.value = value;
// notify [1, 2, value]
}
}
void main() {
final counter = Counter();
autorun((_) => print(counter.value));
print('set value');
counter.value = 1;
counter.value = 2;
counter.value = 3;
Future.delayed(Duration(milliseconds: 1000));
print('setValue with action');
counter.setValue(3);
Future.delayed(Duration(milliseconds: 1000));
print('setValue without action');
counter.setValueWithoutAction(3);
Future.delayed(Duration(milliseconds: 1000));
}
0
set value
1
2
3
setValue with action
Do stuff
3
setValue without action
Do stuff
1
2
3
@amondnet
Hey! It seems like you may have misread what I wrote.
I was more so asking if the action needs to be on the function that is actually changing the variable or both.