The Observable Triad
ACTIONS ==> OBSERVABLES ==> REACTIONS
- Concept of reactive-data
- Various decorators to simplify marking properties as observables
@observable
observable.ref
observable.shallow
- Can be applied to objects, arrays and maps
- Always use classes. Occassionally rely on
decorate()
orextendObservable()
- Computed properties
- Also called Derivations, Derived properties
- Think of your reactive-data as a combination of Core Observables + Derived Observables (Computed)
- Reactions in disguise
- Used as decorator:
@computed
- Adds vocabulary of operations and makes it very Domain Driven
- Transactional notifications to changes in observables
- Most often used with decorators:
@action
configure({enforceActions: 'never' | 'observed' | 'always'})
- Use of
runInAction(() => {})
to wrap mutations after an async call
- These are the observers in the system.
- Of 3 kinds:
autorun()
,reaction()
,when()
- Each returns a disposer which can be used to prematurely stop the observation
- UI is modeled as
reaction()
- Long running
- No way to select the observables explicitly
- Selector + Effect function is combined into one
autorun(() => {
const { name, email } = this;
validate({ name, email }, rules);
});
- Long running
- First argument is a selector function
- Second argument is the effect function
reaction(() => this.isComplete, () => this.notifyServer());
delay
can be used to debounce the side-effect for bothautorun()
andreaction()
- More options available like
name
,onError
, etc.
- One time only
- Automatically dispose after completion of side-effect
- First argument is a predicate function
- When it becomes true, the side-effect is executed
- Used as a promise to await and run the side-effect as a continuation. Handy way to mark junctions in your logic.
async function showAlertOnExpirty() {
await when(() => this.hasOfferExpired);
showAlert('Offer Expired');
}
fromPromise()
createViewModel()