Skip to content

Latest commit

 

History

History
478 lines (351 loc) · 41.5 KB

README.md

File metadata and controls

478 lines (351 loc) · 41.5 KB

言語: 英語 | ポルトガル語 | 中国語 | 日本語 | 韓国語

mobx.dart



pub package pub package pub package

Build Status Publish Coverage Status Netlify Status

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

MobX の Dart 言語バージョン。

透明な関数型リアクティブプログラミング(TFRP)を使用して、Dart アプリの状態管理を強化します。

紹介

MobX は、アプリケーションのリアクティブデータを UI に簡単に接続できる状態管理ライブラリです。 この接続は完全に自動であり、非常に自然に感じられます。アプリケーション開発者として、UI(および他の場所)で消費する必要があるリアクティブデータに純粋に集中し、両者を同期させることを心配する必要はありません。

これは本当に魔法ではありませんが、消費されているもの(オブザーバブル)とどこで(リアクション)に関するいくつかのスマートな機能があり、自動的に追跡します。オブザーバブルが変更されると、すべてのリアクションが再実行されます。興味深いのは、これらのリアクションは、単純なコンソールログ、ネットワーク呼び出しから UI の再レンダリングまで、何でもかまわないということです。

MobX は JavaScript アプリにとって非常に効果的なライブラリであり、Dart 言語へのこの移植は同じレベルの生産性をもたらすことを目的としています。

スポンサー

私たちのスポンサーに非常に感謝しています。彼らのおかげで、私たちはオープンソースソフトウェア(OSS)プログラムの一部になることができました。 [スポンサーになる]

始める

MobX.dart 公式サイトの入門ガイド.

深く掘り下げる

MobX をより深く理解するには、MobX クイックスタートガイド をご覧ください。この本は JavaScript バージョンの MobX を使用していますが、コアの概念は Dart および Flutter バージョンにも完全に適用できます。

コアコンセプト

MobX Triad

MobX の中心には、オブザーバブル(Observables)、アクション(Actions)、リアクション(Reactions)という 3 つの重要な概念があります。

オブザーバブル(Observables)

オブザーバブルは、アプリケーションのリアクティブ状態を表します。これらは、単純なスカラーから複雑なオブジェクトツリーまでさまざまです。アプリケーションの状態をオブザーバブルのツリーとして定義することにより、UI(またはアプリ内の他のオブザーバー)が使用するリアクティブ状態ツリーを公開できます。

単純なリアクティブカウンターは、次のオブザーバブルで表されます。

import 'package:mobx/mobx.dart';

final counter = Observable(0);

クラスなどのより複雑なオブザーバブルも作成できます。

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++;
  }
}

一見すると、これはすぐに手に負えなくなるテンプレートコードのように見えます! これが、上記のコードを次のコードに置き換えることができる mobx_codegen を追加した理由です。

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 increment() {
    value++;
  }
}

クラスのオブザーバブルプロパティをマークするために注釈を使用することに注意してください。はい、ここにはヘッダーのテンプレートコードがありますが、これはどのクラスにも固定されています。より複雑なクラスを構築するにつれて、このテンプレートコードは消え、主に中括弧内のコードに集中するようになります。

注意:注釈は mobx_codegen パッケージを介して利用できます。

計算オブザーバブル(Computed Observables)

何が計算できるか、何が計算されるべきか。自動的に。

アプリケーションの状態は、コア状態と派生状態で構成されます。コア状態は、あなたが扱っているドメインに固有の状態です。たとえば、Contact エンティティがある場合、firstNamelastNameContact のコア状態を形成します。ただし、fullName は派生状態であり、firstNamelastName を組み合わせることによって取得されます。

このようなコア状態または他の派生状態に依存する派生状態は、計算オブザーバブルと呼ばれます。基になるオブザーバブルが変更されると、自動的に同期されます。

MobX の状態 = コア状態 + 派生状態

import 'package:mobx/mobx.dart';

part 'contact.g.dart';

class Contact = ContactBase with _$Contact;

abstract class ContactBase with Store {
  @observable
  String firstName;

  @observable
  String lastName;

  @computed
  String get fullName => '$firstName, $lastName';

}

上記の例では、firstName または lastName が変更されると、fullName は自動的に同期されます。

アクション(Actions)

アクションは、オブザーバブルをどのように変更するかを示します。オブザーバブルを直接変更するのではなく、アクションは変更に意味を追加します。たとえば、単に value++ を実行するのではなく、increment() アクションを発行する方が意味があります。さらに、アクションはすべての通知をバッチ処理し、完了後に変更が通知されるようにします。 したがって、オブザーバーはアクションの原子操作が完了したときにのみ通知されます。

アクションはネストすることもでき、最上位のアクションが完了すると通知が送信されます。

final counter = Observable(0);

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

クラス内でアクションを作成するときは、注釈を利用できます!

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 increment() {
    value++;
  }
}

非同期アクション

MobX.dart は非同期アクションを自動的に処理し、runInAction でコードをラップする必要はありません。

@observable
String stuff = '';

@observable
bool loading = false;

@action
Future<void> loadStuff() async {
  loading = true; //This notifies observers
  stuff = await fetchStuff();
  loading = false; //This also notifies observers
}

リアクション(Reactions)

リアクションは、オブザーバブル、アクション、リアクションの MobX トライアドを完成させます。これらはリアクティブシステムのオブザーバーであり、追跡しているオブザーバブルが変更されると通知されます。リアクションには、以下にリストされているいくつかのフレーバーがあります。すべて ReactionDisposer を返します。これは、リアクションを破棄するために呼び出すことができる関数です。

リアクションの際立った特徴の 1 つは、明示的な配線なしで、すべてのオブザーバブルを自動的に追跡することです。リアクション内でオブザーバブルを読み取る行為だけで、それを追跡するのに十分です!

MobX を使用して記述したコードは、文字通り儀式がないように見えます!

ReactionDisposer autorun(Function(Reaction) fn)

リアクションをすぐに実行し、fn 内で使用されるオブザーバブルの変更時にも実行します。

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)

predicate() 関数内で使用されるオブザーバブルを監視し、predicate が異なる値を返すと effect() を実行します。predicate 内のオブザーバブルのみが追跡されます。

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)

predicate() 内で使用されるオブザーバブルを監視し、true を返すと effect() を実行します。effect() が実行されると、when は自動的に破棄されます。したがって、when をワンタイムリアクションと見なすことができます。when() を早期に破棄することもできます。

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)

when と似ていますが、Future を返します。これは、predicate()true を返すと完了します。これは、predicate()true になるのを待つ便利な方法です。

final completed = Observable(false);

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

  print('Completed');
}

Observer

アプリで最も視覚的なリアクションの 1 つは UI です。Observer ウィジェット(flutter_mobx パッケージの一部)は、builder 関数で使用されるオブザーバブルの細かいオブザーバーを提供します。これらのオブザーバブルが変更されると、Observer は再構築されてレンダリングされます。

以下は、カウンターの例の全体です。

import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
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 increment() {
    value++;
  }
}

class CounterExample extends StatefulWidget {
  const CounterExample({Key key}) : super(key: key);

  @override
  _CounterExampleState createState() => _CounterExampleState();
}

class _CounterExampleState extends State<CounterExample> {
  final _counter = Counter();

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
          title: const Text('Counter'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text(
                'You have pushed the button this many times:',
              ),
              Observer(
                  builder: (_) => Text(
                        '${_counter.value}',
                        style: const TextStyle(fontSize: 20),
                      )),
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _counter.increment,
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
      );
}

貢献

ここまで読んでいただきありがとうございます🎉🎉🎉。成長し続ける MobX.dart コミュニティに貢献する方法はいくつかあります。

  • "good first issue" とマークされた問題を選択します
  • 機能、品質向上の提案を行う
  • バグを報告する
  • バグを修正する
  • 議論に参加し、意思決定を支援する
  • ドキュメントを作成および改善します。ドキュメントは非常に重要であり、その重要性は言うまでもありません!
  • プルリクエストを送信する
  • 参加して Join the chat at https://discord.gg/dNHY52k

貢献者 ✨

All Contributors

これらの素晴らしい人々に感謝します! (絵文字キー):

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

📖

このプロジェクトは all-contributors 仕様に従っています。あらゆる種類の貢献を歓迎します!