Mobx Providers In Flutter :
MobX is a one of state management, originally developed for JavaScript but now is there for Dart also. MobX is a Battle tested state management library Transparently Functional Reactive programming (TFRP).
Widgets are the basic building blocks that can be reused at a later time. They can be Classified into — stateless(No internal state exist) & stateful(Dynamic) widgets .
SetState has its own limitations:
1) Share More state across components — Internal state management become troublesome when you need to share more states across components.
2) Distant leaf components need access to states — Intermediary components doesn’t need to know becomes a problem as data gets shared to all pass through components.
Mobx
mobx_codegen: a code generation library for MobX that allows usage of MobX annotations
build_runner: a stand-alone library to run code generation operations
mobx: Dart port of MobX for writing state-modifying logic
flutter_mobx: Flutter integration for MobX that provides the Observer widget that automatically rebuilds based on changes to observable state
Flutter Mobx using .g file geneated terminal command
1) flutter packages pub run build_runner build
2) flutter packages pub run build_runner watch
3) flutter packages pub run build_runner watch –delete-conflicting-outputs
- Observables are variables which represent the reactive-state of our application. They are also called ‘Event Generators’ because the state or value of an observable changes from time to time.
- Actions are functions that decide how to mutate the observables. Because of this property, they are also called ‘Mutators’.
- Computed Observables are values which depend upon observables and get triggered when the observable they depend on, changes its state.
- Observer Widgets are a special type of widget which acts as a listener to the observable properties being rendered on the screen, and simply changes the state and re-renders them whenever any change is observed.
Counter Package :
counter_store.dart
import 'package:mobx/mobx.dart'; import 'package:pattern_mobx_provider/base/mobx/mobx_base/mobx_base.dart'; part 'counter_store.g.dart'; class CounterStore = _CounterStore with _$CounterStore; abstract class _CounterStore extends MobxBase with Store { _CounterStore():_counter=0; @observable int _counter; int get counter => _counter; @action void increment() => _counter++; void dispose() {} }
counter_store.g.dart
// GENERATED CODE - DO NOT MODIFY BY HAND part of 'counter_store.dart'; // ************************************************************************** // StoreGenerator // ************************************************************************** // ignore_for_file: non_constant_identifier_names, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic mixin _$CounterStore on _CounterStore, Store { final _$_counterAtom = Atom(name: '_CounterStore._counter'); @override int get _counter { _$_counterAtom.context.enforceReadPolicy(_$_counterAtom); _$_counterAtom.reportObserved(); return super._counter; } @override set _counter(int value) { _$_counterAtom.context.conditionallyRunInAction(() { super._counter = value; _$_counterAtom.reportChanged(); }, _$_counterAtom, name: '${_$_counterAtom.name}_set'); } final _$_CounterStoreActionController = ActionController(name: '_CounterStore'); @override void increment() { final _$actionInfo = _$_CounterStoreActionController.startAction(); try { return super.increment(); } finally { _$_CounterStoreActionController.endAction(_$actionInfo); } } }
counter_widget.dart
import 'package:flutter/material.dart'; import 'package:pattern_mobx_provider/base/mobx/mobx_providers/mobx_stateful_provider.dart'; import 'counter_store.dart'; class CounterWidget extends StatelessWidget { @override Widget build(BuildContext context) { return MobxStatefulProvider<CounterStore>( store: CounterStore(), builder: (context, store) { return Scaffold( floatingActionButton: FloatingActionButton( onPressed: store.increment, child: Icon(Icons.add)), appBar: AppBar( title: Text('mobx provider example'), ), body: Center( child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('counter value is ${store.counter}'), ], ), ), ); }, ); } }
mobx Package
mobx_base
- mobx_base.dart
- mobx_b ase.g.dart
mobx_base.dart
import 'package:mobx/mobx.dart'; part 'mobx_base.g.dart'; enum StoreState { loading, sucess, initial, error } ///this is the base class for all mobx classes that need to be attached to the ui. ///it contains some helper states and function that make it easier ///in the ui for determining which widget you should show to the user. ///despite the class has [Store] mixin , you should write [with store] exciplictly ///in your own class in order to generate the code. abstract class MobxBase = _MobxBase with _$MobxBase; abstract class _MobxBase with Store { _MobxBase() : _state = StoreState.initial; @observable StoreState _state; ///get the state of the store StoreState get state => _state; bool get isLoading => _state == StoreState.loading; bool get isError => _state == StoreState.error; bool get isSuccess => _state == StoreState.sucess; bool get isInitial => _state == StoreState.initial; @action void changeState(StoreState state) => _state = state; @action void toLoadingState() => _state = StoreState.loading; @action void toSuccessState() => _state = StoreState.sucess; @action void toErrorState() => _state = StoreState.error; @action void toInitialState() => _state = StoreState.initial; ///this function is called when the [observer stateful provider] is disposed void dispose(); }
mobx_b ase.g.dart
// GENERATED CODE - DO NOT MODIFY BY HAND part of 'mobx_base.dart'; // ************************************************************************** // StoreGenerator // ************************************************************************** // ignore_for_file: non_constant_identifier_names, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic mixin _$MobxBase on _MobxBase, Store { final _$_stateAtom = Atom(name: '_MobxBase._state'); @override StoreState get _state { _$_stateAtom.context.enforceReadPolicy(_$_stateAtom); _$_stateAtom.reportObserved(); return super._state; } @override set _state(StoreState value) { _$_stateAtom.context.conditionallyRunInAction(() { super._state = value; _$_stateAtom.reportChanged(); }, _$_stateAtom, name: '${_$_stateAtom.name}_set'); } final _$_MobxBaseActionController = ActionController(name: '_MobxBase'); @override void changeState(StoreState state) { final _$actionInfo = _$_MobxBaseActionController.startAction(); try { return super.changeState(state); } finally { _$_MobxBaseActionController.endAction(_$actionInfo); } } @override void toLoadingState() { final _$actionInfo = _$_MobxBaseActionController.startAction(); try { return super.toLoadingState(); } finally { _$_MobxBaseActionController.endAction(_$actionInfo); } } @override void toSuccessState() { final _$actionInfo = _$_MobxBaseActionController.startAction(); try { return super.toSuccessState(); } finally { _$_MobxBaseActionController.endAction(_$actionInfo); } } @override void toErrorState() { final _$actionInfo = _$_MobxBaseActionController.startAction(); try { return super.toErrorState(); } finally { _$_MobxBaseActionController.endAction(_$actionInfo); } } @override void toInitialState() { final _$actionInfo = _$_MobxBaseActionController.startAction(); try { return super.toInitialState(); } finally { _$_MobxBaseActionController.endAction(_$actionInfo); } } }
mobx_providers Package
- mobx_stateful_provider.dart
- mobx_stateless_provider.dart
mobx_stateful_provider.dart
import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:pattern_mobx_provider/base/mobx/mobx_base/mobx_base.dart'; ///This is like the [Observer stateless Provider] but it contains [Stateful widget] ///instead of [Stateless Widget], this allows you to call a function [initFunction] /// that you want to be invoked in the [init State] /// it also preserve the [state of the store] in hot reload /// if you press hot reload with the default [observer Provider] it'll lose its state /// when the [current widget] is removed from the widget tree the [StatefulObserverProvider] will /// call [disopse function] for the store /// this package is inspired from [Filled Stacks] package [view model provider] class MobxStatefulProvider<T extends MobxBase> extends StatefulObserverWidget { final T store; final Widget Function(BuildContext context, T store) builder; final void Function(T store) initFunction; MobxStatefulProvider({ ///the name of your widget , that's used for debuging purposes only ///it's the same as the name parameter in the [observer] widgets String name, Key key, @required this.store, @required this.builder, this.initFunction, }) : super(key: key, name: name); @override _MobxStatefulProviderState<T> createState() => _MobxStatefulProviderState<T>(); } class _MobxStatefulProviderState<T extends MobxBase> extends State<MobxStatefulProvider<T>> { T _store; @override void initState() { super.initState(); _store = widget.store; if (widget.initFunction != null) widget.initFunction(_store); } @override void dispose() { _store.dispose(); super.dispose(); } @override Widget build(BuildContext context) => widget.builder(context, _store); }
mobx_stateless_provider.dart
import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:pattern_mobx_provider/base/mobx/mobx_base/mobx_base.dart'; ///This widget is like default [observer widget] but with ///easier way to bind your stores with the UI ///this widget is extends [stateless Observer widget] which extends [stateless wisget] ///so it's basically a [stateless widget] ///NOTE: hence this is a [stateless widget] it doesn't hold any state , even the state of ///ITS STORE, the store should be SINGLETON and be binded with the widget by injector service ///like provider , get_it ,etc /// this package is inspired from [Filled Stacks] package [view model provider] class MobxStatelessProvider<T extends MobxBase> extends StatelessObserverWidget { final T store; final Widget Function(BuildContext context, T store) builder; MobxStatelessProvider({ ///the name of your widget , that's used for debuging purposes only ///it's the same as the name parameter in the [observer] widget String name, Key key, @required this.store, @required this.builder, }) : super(key: key, name: name); @override Widget build(BuildContext context) => builder(context, store); }
main.dart
import 'package:flutter/material.dart'; import 'counter/counter_widget.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: CounterWidget(), ); } }
pubspec.yaml
name: pattern_mobx_provider description: A new Flutter application. version: 1.0.0+1 environment: sdk: ">=2.1.0 <3.0.0" dependencies: flutter: sdk: flutter mobx: flutter_mobx: cupertino_icons: dev_dependencies: build_runner: mobx_codegen: flutter_test: sdk: flutter flutter: uses-material-design: true
The flutter tutorial is a website that bring you the latest and amazing resources of code. All the languages codes are included in this website. The languages like flutter, android, java,kotlin etc.with the help of this languages any user can develop the beautiful application
For more information about Flutter. visit www.fluttertutorial.in