haste 0.0.1
haste: ^0.0.1 copied to clipboard
A collection of actions that help you write StatelessWidgets with haste.
Haste ⚡️ #
You're locked in. All of a sudden you realize that your StatelessWidget widget needs a TextEditingController, or maybe a FocusNode or somple simple piece of boolean state. You don't have time to convert it to a StatefulWidget. You need a one-line solution. You need to act with Haste.
Similarly to the awesome Flutter hooks package, Haste lets you perform stateful actions in a StatelessWidget. Let's see how it looks!
Pre-haste #
class MyForm extends StatefulWidget {
final Widget Function({
required String name,
required int age,
}) submit;
MyForm({ required this.submit });
@override
MyFormState createState() => MyFormState();
}
class MyFormState extends State<MyForm> {
int _age = 0;
TextEditingController _controller = TextEditingController();
@override
build(context) {
return Column(
children: [
TextField(controller: _controller, hintText: 'Name'),
AgePicker(initialValue: 0, onPick: (newAge) => setState(() => _age = newAge)),
TextButton(
child: Text('Submit'),
onPressed: () => widget.submit(age: _age, name: _controller.text),
),
]
)
}
}
Post-haste #
class MyForm extends StatelessWidget with Haste {
final Widget Function({
required String name,
required int age,
}) submit;
MyForm({ required this.submit });
@override
build(context) {
final (age, setAge) = state(0);
final controller = memo(() => TextEditingController());
return Column(
children: [
TextField(controller: controller, hintText: 'Name'),
AgePicker(initialValue: 0, onPick: (newAge) => setAge(newAge)),
TextButton(
child: Text('Submit'),
onPressed: () => widget.submit(age: age, name: _controller.text),
),
]
)
}
}
Actions #
init➡️ Run some code when aStatelessWidgetis initialized.memo➡️ Memoize a value like aTextEditingController,FocusNode, etc.state➡️ Setup a mutable piece of state in aStatelessWidget.future➡️ Subscribe to a future.stream➡️ Subscribe to a stream.onChange➡️ Run some code when a value changes.dispose➡️ Run some code when aStatelessWidgetis disposed.previous➡️ Return the previous value from the last build.
Install #
flutter pub add haste
Demos #
- User form (actions -
state) - Load user (actions -
state,future) - Football score (actions -
stream,init,onChange)
Extensions #
Want extended actions for a particular library? You can find some extension packages below:
- Computables - A reactive state primitive library. Extension.
- Loon - Loon is a reactive document data store for Flutter. Extension.
Creating extensions #
Need an action you don't see yet? Create your own!
Let's take the example of creating an extended action called counter that periodically increments a value and rebuilds the widget:
class MyWidget extends StatelessWidget with Haste {
@override
build(context) {
// Increment a counter beginning at 0 every 2 seconds.
final count = counter(0, Duration(seconds: 2));
return Text("Count: $count"); // Count: 0, Count: 1, Count: 2...
}
}
And here is how you would implement it:
class CounterAction extends HasteAction<int> {
int _count;
late final Timer _timer;
CounterAction(this._count, Duration duration) {
_timer = Timer.periodic(duration, (_) {
_count++;
markNeedsBuild();
});
}
@override
dispose() {
_timer.cancel();
super.dispose();
}
}
class CounterActionBuilder extends HasteActionBuilder {
const CounterActionBuilder();
int call(int initialValue, Duration duration, {Key? key}) {
// A new counter action is built whenever the provided key changes.
final action = rebuild(key, () => CounterAction(initialValue, duration));
return action._count;
}
}
// Finally, extend the set of existing haste actions with the counter extension.
extension HasteCounterAction on Haste {
CounterActionBuilder get counter => const CounterActionBuilder();
}