Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

MobX for the Dart language. Hassle-free, reactive state-management for your Dart and Flutter apps.

License

NotificationsYou must be signed in to change notification settings

mobxjs/mobx.dart

Repository files navigation

Language:English |Português |Chinese |Japanese |한국어

mobx.dart



pub packagepub packagepub package

Build StatusPublishCoverage StatusNetlify StatusMutable.ai Auto Wiki

Join the chat at https://discord.gg/dNHY52k

MobX for the Dart language.

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

We are looking for maintainers. Reach out on Discord or GitHub Issues!

Introduction

MobX is a state-management library that makes it simple to connect thereactive data of your application with the UI. This wiring is completely automaticand feels very natural. As the application-developer, you focus purely on what reactive-dataneeds to be consumed in the UI (and elsewhere) without worrying about keeping the twoin 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 theobservableschange, allreactions are re-run. What's interesting is that these reactions can be anything from a simpleconsole log, a network call to re-rendering the UI.

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

Sponsors

We are very thankful to our sponsors to make us part of theirOpen Source Software (OSS) program. [Become a sponsor]

Past Sponsors

Get Started

Follow along with theGetting Started guide on the MobX.dart Website.

Go deep

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

Core Concepts

MobX Triad

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

Observables

Observables represent the reactive-state of your application. They can be simple scalars to complex object trees. Bydefining the state of the application as a tree of observables, you can expose areactive-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.

classCounter {Counter() {    increment=Action(_increment);  }final _value=Observable(0);intget value=> _value.value;setvalue(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 addedmobx_codegen to the mix that allows you to replace the above code with the following:

import'package:mobx/mobx.dart';part'counter.g.dart';classCounter=CounterBasewith_$Counter;abstractclassCounterBasewithStore {@observableint value=0;@actionvoidincrement() {    value++;  }}

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

Note: Annotations are available via themobx_codegen package.

Readonly

If you want to reduce your code you may want to swap@observable for@readonly.For every private variable it generates a public getter such that the client of your storecan't change its value. Read more about ithere

Computed Observables

What can be derived, should be derived. Automatically.

The state of your application consists ofcore-state andderived-state. Thecore-state is state inherent to the domain you are dealing with. For example, if you have aContact entity, thefirstName andlastName form thecore-state ofContact. However,fullName isderived-state, obtained by combiningfirstName andlastName.

Suchderived state, that depends oncore-state orother derived-state is called aComputed Observable. It is automatically kept in sync when its underlying observables change.

State in MobX = Core-State + Derived-State

import'package:mobx/mobx.dart';part'contact.g.dart';classContact=ContactBasewith_$Contact;abstractclassContactBasewithStore {@observableString firstName;@observableString lastName;@computedStringget fullName=>'$firstName, $lastName';}

In the example abovefullName is automatically kept in sync if eitherfirstName and/orlastName changes.

Actions

Actions are how you mutate the observables. Rather than mutating them directly, actionsadd a semantic meaning to the mutations. For example, instead of just doingvalue++,firing anincrement() action carries more meaning. Besides, actions also batch upall 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 outwhen 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';classCounter=CounterBasewith_$Counter;abstractclassCounterBasewithStore {@observableint value=0;@actionvoidincrement() {    value++;  }}

Asynchronous Actions

MobX.dart handles asynchronous actions automatically and does not require wrapping the code withrunInAction.

@observableString stuff='';@observablebool loading=false;@actionFuture<void>loadStuff()async {  loading=true;//This notifies observers  stuff=awaitfetchStuff();  loading=false;//This also notifies observers}

Reactions

Reactions complete theMobX triad ofobservables,actions andreactions. They arethe observers of the reactive-system and get notified whenever an observable theytrack is changed. Reactions come in few flavors as listed below. All of themreturn aReactionDisposer, a function that can be called to dispose the reaction.

Onestriking feature of reactions is that theyautomatically track all the observables without any explicit wiring. The act ofreading an observable within a reaction is enough to track it!

The code you write with MobX appears to be literally ceremony-free!

ReactionDisposer autorun(Function(Reaction) fn)

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

import'package:mobx/mobx.dart';final greeting=Observable('Hello World');final dispose=autorun((_){print(greeting.value);});greeting.value='Hello MobX';// Done with the autorun()dispose();// Prints:// Hello World// Hello MobX

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

Monitors the observables used inside thepredicate() function and runs theeffect() whenthe predicate returns a different value. Only the observables insidepredicate() are tracked.

import'package:mobx/mobx.dart';final greeting=Observable('Hello World');final dispose=reaction((_)=> greeting.value, (msg)=>print(msg));greeting.value='Hello MobX';// Cause a change// Done with the reaction()dispose();// Prints:// Hello MobX

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

Monitors the observables used insidepredicate() and runs theeffect()when it returnstrue. After theeffect() is run,when automatically disposes itself. So you can think ofwhen as aone-timereaction. You can also disposewhen() pre-maturely.

import'package:mobx/mobx.dart';final greeting=Observable('Hello World');final dispose=when((_)=> greeting.value=='Hello MobX', ()=>print('Someone greeted MobX'));greeting.value='Hello MobX';// Causes a change, runs effect and disposes// Prints:// Someone greeted MobX

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

Similar towhen but returns aFuture, which is fulfilled when thepredicate() returnstrue. This is a convenient way of waiting for thepredicate() to turntrue.

final completed=Observable(false);voidwaitForCompletion()async {awaitasyncWhen(()=> _completed.value==true);print('Completed');}

Observer

One of the most visual reactions in the app is the UI. TheObserver widget (which is part of theflutter_mobx package), provides a granular observer of the observables used in itsbuilder function. Whenever these observables change,Observer rebuilds and renders.

Below is theCounter example in its entirety.

import'package:flutter/material.dart';import'package:flutter_mobx/flutter_mobx.dart';import'package:mobx/mobx.dart';part'counter.g.dart';classCounter=CounterBasewith_$Counter;abstractclassCounterBasewithStore {@observableint value=0;@actionvoidincrement() {    value++;  }}classCounterExampleextendsStatefulWidget {constCounterExample({Key key}):super(key: key);@override_CounterExampleStatecreateState()=>_CounterExampleState();}class_CounterExampleStateextendsState<CounterExample> {final _counter=Counter();@overrideWidgetbuild(BuildContext context)=>Scaffold(        appBar:AppBar(          title:constText('Counter'),        ),        body:Center(          child:Column(            mainAxisAlignment:MainAxisAlignment.center,            children:<Widget>[constText('You have pushed the button this many times:',              ),Observer(                  builder: (_)=>Text('${_counter.value}',                        style:constTextStyle(fontSize:20),                      )),            ],          ),        ),        floatingActionButton:FloatingActionButton(          onPressed: _counter.increment,          tooltip:'Increment',          child:constIcon(Icons.add),        ),      );}

Contributing

If you have read up till here, then 🎉🎉🎉. There are couple of ways in which you can contribute tothe growing community ofMobX.dart.

  • Pick up any issue marked with"good first issue"
  • Propose any feature, enhancement
  • Report a bug
  • Fix a bug
  • Participate in a discussion and help in decision making
  • Write and improve somedocumentation. Documentation is super critical and its importancecannot be overstated!
  • Send in a Pull Request :-)
  • Chime in andJoin the chat at https://discord.gg/dNHY52k

Contributors ✨

All Contributors

Thanks goes to these wonderful people (emoji key):

Pavan Podila
Pavan Podila

💻📖👀
katis
katis

💻🤔👀⚠️
Scott Hyndman
Scott Hyndman

💻🤔👀⚠️
Michael Bui
Michael Bui

💻📖👀💡
Remi Rousselet
Remi Rousselet

💻📖👀
adiaKhaitan
adiaKhaitan

📖
Jacob Moura
Jacob Moura

💻📖🌍
Daniel Albuquerque
Daniel Albuquerque

🌍
Marco Scannadinari
Marco Scannadinari

📖
lsaudon
lsaudon

💻📖
Efthymis Sarmpanis
Efthymis Sarmpanis

💻
Giri Jeedigunta
Giri Jeedigunta

📖💡
Hebri Ramnath Nayak
Hebri Ramnath Nayak

📖
Robert Brunhage
Robert Brunhage

📖
Brady Trainor
Brady Trainor

📖
Kushagra Saxena
Kushagra Saxena

📖💡
Pedro Massango
Pedro Massango

🌍
Peter Czibik
Peter Czibik

💻
Luan Nico
Luan Nico

📖
Kobi
Kobi

💻
Ryan
Ryan

📖
Ivan Terekhin
Ivan Terekhin

💻
Yoav Rofé
Yoav Rofé

📖
Mateusz Wojtczak
Mateusz Wojtczak

📖
Timur Artikov
Timur Artikov

💻
Saurabh Sohoni
Saurabh Sohoni

📖
renanzdm
renanzdm

📖
Rachman Chavik
Rachman Chavik

💻
Nathan Cabasso
Nathan Cabasso

🐛💻
geisterfurz007
geisterfurz007

📖🖋
Romuald Barbe
Romuald Barbe

💻
Alexander Mazuruk
Alexander Mazuruk

💡
Alberto Bonacina
Alberto Bonacina

📖
Roland Ibragimov
Roland Ibragimov

📖
zyzhao
zyzhao

📖
Xinhai Wang
Xinhai Wang

📖
Henry Mayer
Henry Mayer

💻⚠️
Sergey
Sergey

💻⚠️
Jason Rai
Jason Rai

📖
Joshua de Guzman
Joshua de Guzman

💡
Jan Hertlein
Jan Hertlein

📖
Evo Stamatov
Evo Stamatov

💻
Davi Eduardo
Davi Eduardo

📖
Leonardo Custodio
Leonardo Custodio

💻📖
Prince Srivastava
Prince Srivastava

💡💻
Muhammad Muhajir
Muhammad Muhajir

📖
D
D

📖
David Martos
David Martos

💻
Issa Nimaga
Issa Nimaga

📖
Ascênio
Ascênio

💻📖
Alex Isaienko
Alex Isaienko

💻
Moritz Weber
Moritz Weber

💻
Carter Snook
Carter Snook

📖
Brian Robles
Brian Robles

💻⚠️
harrypunk
harrypunk

📖
Ikko Ashimine
Ikko Ashimine

📖
amond
amond

💻⚠️👀📖
fzyzcjy
fzyzcjy

💻📖👀
Vandad Nahavandipoor
Vandad Nahavandipoor

📖
Sergey Molchanovsky
Sergey Molchanovsky

💻
ko16a46
ko16a46

💻
Yatharth Chauhan
Yatharth Chauhan

📖
Parth Baraiya
Parth Baraiya

💻🐛
Altynbek Aidarbekov
Altynbek Aidarbekov

💻
CpedniyNikon
CpedniyNikon

📖
Tirth
Tirth

📖
Joshua Wade
Joshua Wade

💻

This project follows theall-contributors specification. Contributions of any kind welcome!

About

MobX for the Dart language. Hassle-free, reactive state-management for your Dart and Flutter apps.

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Sponsor this project

    Contributors75


    [8]ページ先頭

    ©2009-2025 Movatter.jp