Features
This package contains some base classes designed to improve experience of using Signals state management.
PassiveSignalState
- a state class that doesn't automatically rebuild the widget on model changes. You have to wrap widgets that should be rebuilt withWatch
orWatch.builder
. There is also the.watch(context)
extension method that can be used to rebuild a widget when a signal changes.ReactiveSignalState
- a state class that automatically rebuilds the widget on model changes. It usesWatch
widget under the hood.
Usage
To use this package, add Signals as a dependency in your pubspec.yaml file.
Extend your ScreenModel class from SignalModel
:
class MainScreenModel extends SignalModel {
Add signals to your model:
final Signal<int> counter = signal(0);
Initialize computedModel
in the constructor to change state of the model when signals change.
If using multiple signals, don't forget to add them. computedModel
is a signal that changes its value when any of the signals it depends on changes.
It handles int values, so if you need to use other types, you have to compute
their hashes:
final Signal<int> counter = signal(0);
final Signal<String> text = signal('');
MainScreenModel() {
computedModel = computed(
() => counter.value.hashCode ^ text.value.hashCode,
);
}
Extend your stateful widget state from PassiveSignalState
to manually control widget rebuilds:
class _MainScreenState extends PassiveSignalState<MainScreenModel, MainScreen>
or ReactiveSignalState
to automatically rebuild widget on model changes:
class _MainScreenState extends ReactiveSignalState<MainScreenModel, MainScreen>
Create Model instance in createModel
function:
MainScreenModel createModel() => MainScreenModel();
Write you widget body in buildWidget
instead of build
@override
Widget buildWidget(BuildContext context) {
return Scaffold(...);
}
If using PassiveSignalState
you have to manually rebuild the widget when model changes:
with Watch
widget:
Watch(
(context) => Text(
'${stateSignals.counter}',
style: Theme.of(context).textTheme.headlineMedium,
),
),
with Watch.builder
widget:
Watch.builder(
builder: (context) => Text(
'${stateSignals.counter}',
style: Theme.of(context).textTheme.headlineMedium,
),
),
or use the .watch(context)
extension method:
Text(
'${stateSignals.counter}',
style: Theme.of(context).textTheme.headlineMedium,
).watch(context),