mobx 0.0.27 copy "mobx: ^0.0.27" to clipboard
mobx: ^0.0.27 copied to clipboard

outdated

MobX is a library for reactively managing the state of your applications. Use the power of observables, actions, and reactions to supercharge your Dart and Flutter apps.

mobx.dart #

pub package Build Status Coverage Status

MobX for the Dart language.

Supercharge the state-management in your Dart apps with Transparent Functional Reactive Programming (TFRP)

Introduction #

MobX is a state-management library that makes it simple to connect the reactive data of your application with the UI. This wiring is completely automatic and feels very natural. As the application-developer, you focus purely on what reactive-data needs to be consumed in the UI (and elsewhere) without worrying about keeping the two in sync.

It's not really magic but it does have some smarts around what is being consumed (observables) and where (reactions), and automatically tracks it for you. When the observables change, all reactions are re-run. What's interesting is that these reactions can be anything from a simple console log, a network call to re-rendering the UI.

MobX has been a very effective library for the JavaScript apps and this port to the Dart language aims to bring the same levels of productivity.

Go deep #

For a deeper coverage of MobX, do check out MobX Quick Start Guide. Although the book uses the JavaScript version of MobX, the concepts are 100% applicable to Dart and Flutter.

Core Concepts #

MobX Triad

At the heart of MobX are three important concepts: Observables, Actions and Reactions.

Observables #

Observables represent the reactive-state of your application. They can be simple scalars to complex object trees. By defining the state of the application as a tree of observables, you can expose a reactive-state-tree that the UI (or other observers in the app) consume.

A simple reactive-counter is represented by the following observable:

import 'package:mobx/mobx.dart';

final counter = Observable(0);

More complex observables, such as classes, can be created as well.

class Counter {
  Counter() {
    increment = Action(_increment);
  }

  final _value = Observable(0);
  int get value => _value.value;

  set value(int newValue) => _value.value = newValue;
  Action increment;

  void _increment() {
    _value.value++;
  }
}

On first sight, this does look like some boilerplate code which can quickly go out of hand! This is why we added mobx_codegen to the mix that allows you to replace the above code with the following:

import 'package:mobx/mobx.dart';

part 'counter.g.dart';

class Counter = CounterBase with _$Counter;

abstract class CounterBase implements Store {
  @observable
  int value = 0;

  @action
  void increment() {
    value++;
  }
}

Note the use of annotations to mark the observable properties of the class. Yes, there is some header boilerplate here but its fixed for any class. As you build more complex classes this boilerplate will fade away and you will mostly focus on the code within the braces.

Note: Annotations are available via the mobx_codegen package.

Actions #

Actions are how you mutate the observables. Rather than mutating them directly, actions add a semantic meaning to the mutations. For example, instead of just doing value++, firing an increment() action carries more meaning. Besides, actions also batch up all the notifications and ensure the changes are notified only after they complete. Thus the observers are notified only upon the atomic completion of the action.

Note that actions can also be nested, in which case the notifications go out when the top-most action has completed.

final counter = Observable(0);

final increment = Action((){
  counter.value++;
});

When creating actions inside a class, you can take advantage of annotations!

import 'package:mobx/mobx.dart';

part 'counter.g.dart';

class Counter = CounterBase with _$Counter;

abstract class CounterBase implements Store {
  @observable
  int value = 0;

  @action
  void increment() {
    value++;
  }
}

Reactions #

Reactions complete the MobX triad of observables, actions and reactions. They are the observers of the reactive-system and get notified whenever an observable they track is changed. Reactions come in few flavors as listed below. All of them return a ReactionDisposer, a function that can be called to dispose the reaction.

ReactionDisposer autorun(Function(Reaction) fn)

Runs the reaction immediately and also on any change in the observables used inside fn.

ReactionDisposer reaction<T>(T Function(Reaction) predicate, void Function(T) effect)

Monitors the observables used inside the predicate() function and runs the effect() when the predicate returns a different value. Only the observables inside predicate() are tracked.

ReactionDisposer when(bool Function(Reaction) predicate, void Function() effect)

Monitors the observables used inside predicate() and runs the effect() upon a change. After the effect() is run, when automatically disposes itself. So you can think of when as a one-time reaction.

Future<void> asyncWhen(bool Function(Reaction) predicate)

Similar to when but returns a Future, which is fulfilled when the predicate() returns true. This is a convenient way of waiting for the predicate() to turn true.

final completed = Observable(false);

void waitForCompletion() async {
  await asyncWhen(() => _completed.value == true);

  print('Completed');
}
1191
likes
0
pub points
99%
popularity

Publisher

verified publisherdart.pixelingene.com

MobX is a library for reactively managing the state of your applications. Use the power of observables, actions, and reactions to supercharge your Dart and Flutter apps.

Repository (GitHub)
View/report issues

License

unknown (LICENSE)

Dependencies

meta

More

Packages that depend on mobx