StateConsumer<S> class

A widget that combines StateBuilder and StateListener.

StateConsumer is useful when you need a widget that both rebuilds UI and performs side effects (like navigation, showing dialogs) in response to state changes.

{@tool snippet} This example shows how to use StateConsumer for a login form:

// Using StateConsumer in a widget
class LoginScreen extends StatelessWidget {
  final LoginController loginController;

  const LoginScreen({
    required this.loginController,
    super.key,
  });

  @override
  Widget build(BuildContext context) => Scaffold(
    appBar: AppBar(title: Text('Login')),
    body: StateConsumer<LoginState>(
      stateReadable: loginController,
      listener: (context, state) {
        if (state.status == LoginStatus.success) {
          Navigator.of(context).pushReplacementNamed('/home');
        } else if (state.status == LoginStatus.error) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text(state.errorMessage ?? 'Login failed')),
          );
        }
      },
      builder: (context, state, _) => LoginForm(
        isLoading: state.status == LoginStatus.loading,
      ),
    ),
  );
}

// A simple login form widget
class LoginForm extends StatelessWidget {
  final bool isLoading;

  const LoginForm({
    required this.isLoading,
    super.key,
  });

  @override
  Widget build(BuildContext context) => Center(
    child: isLoading
        ? const CircularProgressIndicator()
        : const Text('Login Form'),
  );
}

// Example state and state readable
enum LoginStatus { initial, loading, success, error }

class LoginState {
  final LoginStatus status;
  final String? errorMessage;

  const LoginState({
    this.status = LoginStatus.initial,
    this.errorMessage,
  });
}

// A state readable implementation for login
class LoginController implements StateReadable<LoginState> {
  // Implementation details...

  @override
  LoginState get state => const LoginState(); // Example implementation

  @override
  Stream<LoginState> get stream => Stream.empty(); // Example implementation
}

{@end-tool}

See also:

  • StateBuilder, which only rebuilds the UI in response to state changes.
  • StateListener, which only performs side effects in response to state changes.
  • StateSelector, which rebuilds only when a specific part of the state changes.
Inheritance

Constructors

StateConsumer({required StateReadable<S> stateReadable, required StateWidgetBuilder<S> builder, required StateWidgetListener<S> listener, StateBuilderCondition<S>? buildWhen, StateListenerCondition<S>? listenWhen, Widget? child, Key? key})
Creates a new StateConsumer.
const

Properties

builder StateWidgetBuilder<S>
The builder that builds a widget based on the current state.
final
buildWhen StateBuilderCondition<S>?
Optional condition to determine when the builder should rebuild. If null, the builder will rebuild on every state change.
final
child Widget?
The child of the StateConsumer.
final
hashCode int
The hash code for this object.
no setterinherited
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
listener StateWidgetListener<S>
The function that is called when the state changes.
final
listenWhen StateBuilderCondition<S>?
Optional condition to determine when to call listener. If null, the listener will be called on every state change.
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
stateReadable → StateReadable<S>
The source of the state.
final

Methods

build(BuildContext context) Widget
Describes the part of the user interface represented by this widget.
override
createElement() StatelessElement
Creates a StatelessElement to manage this widget's location in the tree.
inherited
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent 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, int wrapWidth = 65}) 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.
inherited