Provider

Flutter provider package is a simple state management solution. There are few essential provider classes you need to know: Provider, FutureProvider,  ChangeNotifierProvider, ProxyProvider. Here I record some basic usages for provide 5

Provider let you inject a dependency for its decendents.

Provider(
  create: (ctx) => ChickenSoap(),
  child: Container(
    child: Center(
      child: Consumer<ChickenSoap>(builder: (ctx, c, child) {
        return Text('The chicken soap is ${c.taste}');
      })
    ),
  ),
),

class ChickenSoap {
  String taste = 'yummy';
}

Consumer get ChickenSoap from its ancestors

While this works, consumer class does not rebuild depending on ChickenSoap's state

FutureProvider rebuild its watcher when its resolved

FutureProvider(
  create: (ctx) => Future.delayed(Duration(seconds: 5)).then((v) {
    return ChickenSoap();
  }),
  child: Container(
    child: Center(
      child: Consumer<ChickenSoap>(builder: (ctx, c, child) {
        if (c == null) return Container();
        return Text('The chicken soap is ${c.taste}');
      })
    ),
  ),
)

Consumer will build its content twice.

First time with null, second time with the completed future.
FutureBuilder in flutter also build its widget depending on future completion. However, it rebuild all it's subtree.

There's also a StreamProvider that rebuild its watchers when new content is pushed to the stream.

ChangeNotifierProvider rebuild its watcher when notifyListeners method is called


ProxyProvider combine multiple provider into one

MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (context) => Counter()),
    ProxyProvider<Counter, StringCounter>(
      update: (ctx, counter, oldStringCounter) {
        return StringCounter(counter.value);
      },
    ),
  ], 
  child: Container(
    child: Center(
      child: Consumer<StringCounter>(builder: (context, c, child) {
        return RaisedButton(
          child: Text(c.toString()),
          onPressed: () {
            var counter = Provider.of<Counter>(context, listen: false);
            counter.inc();
          },
        );
      })
    ),
  ),
);


class Counter extends ChangeNotifier {
  int value = 0;
  
  inc() {
    value += 1;
    notifyListeners();
  }
}

class StringCounter {
  StringCounter(this.value);

  final int value;

  String toString() {
    return 'You clicked this $value times';
  }
}