ReactiveStatelessWidget constructor

const ReactiveStatelessWidget({
  1. Key? key,
})

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

Implementation

const ReactiveStatelessWidget({Key? key}) : super(key: key);