Consumer class Null safety

Build a widget tree while listening to providers.

Consumer can be used to listen to providers inside a StatefulWidget or to rebuild as few widgets as possible when a provider updates.

As an example, consider:

final helloWorldProvider = Provider((_) => 'Hello world');

We can then use Consumer to listen to helloWorldProvider inside a StatefulWidget like so:

class Example extends StatefulWidget {
  @override
  _ExampleState createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  @override
  Widget build(BuildContext context) {
    return Consumer(
      builder: (context, watch, child) {
        final value = watch(helloWorldProvider);
        return Text(value); // Hello world
      },
    );
  }
}

Note You can watch as many providers inside Consumer as you want to:

Consumer(
  builder: (context, watch, child) {
    final value = watch(someProvider);
    final another = watch(anotherProvider);
    ...
  },
);

Performance optimizations

If your builder function contains a subtree that does not depend on the animation, it is more efficient to build that subtree once instead of rebuilding it on every provider update.

If you pass the pre-built subtree as the child parameter, the Consumer will pass it back to your builder function so that you can incorporate it into your build.

Using this pre-built child is entirely optional, but can improve performance significantly in some cases and is therefore a good practice.

This sample shows how you could use a Consumer

final counterProvider = StateProvider((ref) => 0);

class MyHomePage extends StatelessWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title)
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('You have pushed the button this many times:'),
            Consumer(
              builder: (BuildContext context, ScopedReader watch, Widget child) {
                // This builder will only get called when the counterProvider
                // is updated.
                final count = watch(counterProvider).state;

                return Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    Text('$count'),
                    child,
                  ],
                );
              },
              // The child parameter is most helpful if the child is
              // expensive to build and does not depend on the value from
              // the notifier.
              child: Text('Good job!'),
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.plus_one),
        onPressed: () => context.read(counterProvider).state++,
      ),
    );
  }
}

See also:

  • ConsumerWidget, a base-class for widgets that wants to listen to providers.
Inheritance
Annotations

Constructors

Consumer({Key? key, required ConsumerBuilder builder, Widget? child})
{@template riverpod.consumer}
const

Properties

hashCode int
The hash code for this object. [...]
@nonVirtual, read-only, inherited
key Key?
Controls how one widget replaces another widget in the tree. [...]
final, inherited
runtimeType Type
A representation of the runtime type of the object.
read-only, inherited

Methods

build(BuildContext context, ScopedReader watch) Widget
Describes the part of the user interface represented by this widget. [...]
override
createElement() StatefulElement
Creates a StatefulElement to manage this widget's location in the tree. [...]
inherited
createState() → _ConsumerState
Creates the mutable state for this widget at a given location in the tree. [...]
inherited
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children. [...]
@protected, inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node. [...]
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a non-existent method or property is accessed. [...]
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep. [...]
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) String
A string representation of this object. [...]
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a string representation of this node and its descendants. [...]
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a one-line detailed description of the object. [...]
inherited
toStringShort() String
A short, textual description of this widget.
inherited

Operators

operator ==(Object other) bool
The equality operator. [...]
@nonVirtual, inherited