responder 0.1.0+hotfix.1 responder: ^0.1.0+hotfix.1 copied to clipboard
Stateful builders that accept null returns and avoid rebuild. Useful for listening to streams or providers for things other than builds. Like pushing routes, showing a dialog, etc
Responder #
Stateful builders that accept null returns and avoid rebuild. Useful for listening to streams or providers for things other than builds. Like pushing routes, showing a dialog, etc
Prologue #
It all began when we wanted to show a snackbar in response to a Stream
event. We were greeted with red screens of death.
Apparently we can not show snackbars when widgets are building, but we did not want to build/rebuild the widget tree.
We just wanted to show the snackbar.
Method #
We took the code from StreamBuilder
and modified the subscription to call setState only when something changes.
We also cached the subtree so if builder returns null, we do nothing and inhibit the build. This resulted in a working as expected StreamResponder
widget.
We use provider package a lot and wanted to use the same things with StreamProvider, we have not yet been able to acheive the same results with
Responder
widget.
Responder
-- Not Very Useful at the moment #
For the Responder class, we use it just like a Builder
widget, if we return null from the
WidgetBuilder, the Responder
widget handles it properly.
Follow: (responder_example)[./responder_example] for a simple project
body: Responder(
builder: (context) {
if (i % 10 == 0) {
return null;
} else
return WidgetBody(number: i);
},
),
StreamResponder
-- Working as Expected, Use with Caution #
It all began when we wanted to show a snackbar in response to a Stream
event. We were greeted with red screens of death.
Apparently we can not show snackbars when widgets are building, but we did not want to build/rebuild the widget tree.
We just wanted to show the snackbar.
Follow: (stream_responder_example)[./stream_responder_example] for a simple project.
return Scaffold(
body: StreamResponder(
initialData: 1,
stream: numberStream.numbers,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data % 12 == 0) {
numberStream.cancel();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Scaffold(
body: Center(
child: Text(snapshot.data.toString()),
),
),
),
);
return null;
}
return Center(child: Text(snapshot.data.toString()));
},
),
floatingActionButton: FloatingActionButton(onPressed: () {
numberStream.init();
}),
);
- Use it like you would a StreamBuilder, we have designed the api as close as possible
- You can return a Widget like a normal StreamBuilder and everything will work as expected
- You can return null from the builder, or a
Widget
doing so will inhibit the build, so you can call things related to context - NOTE Be careful not to call context based things and return a Widget at the same time. We still can not get over the platform rules.