ReactiveStatelessWidget class Null safety

Use it instead of StatelessWidget to make the hole sub tree reactive.

Any state consumed in any widget child of the widget where the ReactiveStatelessWidget will be registered.

The list of registered states are updated for each rebuild. And any non used state will be removed from the list of subscribers.

Example:

@immutable
class ViewModel {
  // Inject a reactive state of type int.
  // Works for all primitives, List, Map and Set
  final counter1 = 0.inj();

  // For non primitives and for more options
  final counter2 = RM.inject<Counter>(
    () => Counter(0),
    // State will be redone and undone
    undoStackLength: 8,
    // Build-in logger
    debugPrintWhenNotifiedPreMessage: 'counter2',
  );

  //A getter that uses the state of the injected counters
  int get sum => counter1.state + counter2.state.value;

  incrementCounter1() {
    counter1.state++;
  }

  incrementCounter2() {
    counter2.state = Counter(counter2.state.value + 1);
  }
}
class CounterApp extends ReactiveStatelessWidget {
   const CounterApp();

    @override
    Widget build(BuildContext context) {
      return Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Counter1View(),
          Counter2View(),
          Text('🏁 Result: ${viewModel.sum}'), // Will be updated when sum changes
        ],
      );
    }
  }

  // Child 1 - Plain StatelessWidget
  class Counter1View extends StatelessWidget {
    const Counter1View({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
      return Column(
        children: [
          ElevatedButton(
            child: const Text('🏎️ Counter1 ++'),
            onPressed: () => viewModel.incrementCounter1(),
          ),
          // Listen to the state from parent
          Text('Counter1 value: ${viewModel.counter1.state}'),
        ],
      );
    }
  }

  // Child 2 - Plain StatelessWidget
  class Counter2View extends StatelessWidget {
    const Counter2View({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
      return Column(
        children: [
          ElevatedButton(
            child: const Text('🏎️ Counter2 ++'),
            onPressed: () => viewModel.incrementCounter2(),
          ),
          ElevatedButton(
            child: const Text('⏱️ Undo'),
            onPressed: () => viewModel.counter2.undoState(),
          ),
          Text('Counter2 value: ${viewModel.counter2.state.value}'),
        ],
      );
    }
  }

Important Notes:

ReactiveStatelessWidget offers the following hooks: ReactiveStatelessWidget.didMountWidget, ReactiveStatelessWidget.didUnmountWidget ReactiveStatelessWidget.didAddObserverForDebug ReactiveStatelessWidget.shouldRebuildWidget

didNotifyWidget

Inheritance
Implementers

Constructors

ReactiveStatelessWidget({Key? key})
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) Widget
createElement() StatefulElement
Creates a StatefulElement to manage this widget's location in the tree. [...]
inherited
createState() → _ReactiveStatelessWidgetState
Creates the mutable state for this widget at a given location in the tree. [...]
override
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
didAddObserverForDebug(List<InjectedBaseState> observers) → void
Called in debug mode only when an state is added to the list of listeners
didMountWidget() → void
Called when the widget is first inserted in the widget tree
didNotifyWidget(SnapState snap) → void
Called when the widget is notified to rebuild, it exposes the SnapState of the state that emits the notification
didUnmountWidget() → void
Called when the widget is removed from the widget tree
noSuchMethod(Invocation invocation) → dynamic
Invoked when a non-existent method or property is accessed. [...]
inherited
shouldRebuildWidget(SnapState oldSnap, SnapState currentSnap) bool
Condition on when to rebuild the widget, it exposes the old and the new SnapState of the the state that emits the notification.
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