Flutter bindings for ReduRx.
It provides a Provider
as an InheritedWidget
so you can reach the ReduRx Store wherever you have a BuildContext
.
It also has a Connect
Widget so you can grab a few parts of the State (sub-state/props) and it will automatically recall builder
whenever only this little connected part of the State has changed preventing unnecessary rebuilds.
convert: State -> Props
- A function used bymap
to transform the state in a sub-state/props.where: Props oldProps, Props newProps -> bool
- A function to explicitly filter when thebuilder
should be called.builder: Props newProps -> Widget
- A function that receives the sub-state/props and returns aWidget
.
Connect<State, String>(
convert: (state) => state.title,
where: (oldTitle, newTitle) => newTitle != oldTitle,
builder: (title) => Text(title),
)
By default, Connect
will only call builder
if the props aren't null
, otherwise it renders an empty Container
.
If you want to handle null values by youself, set the nullable
property to true
:
Connect<State, String>(
convert: (state) => state.title,
where: (oldTitle, newTitle) => newTitle != oldTitle,
builder: (title) => Text(title),
nullable: true,
)
store
- A ReduRxStore
.child
- Your application'sWidget
.static dispatch<S>(BuildContext, ActionType)
- Helper to calldispatch
on the Provider's context Store.
Provider(
store: Store<State>(State('Initial title')),
child: App(),
)
Provider.dispatch<State>(context, ChangeTitle('New title'));
For a better understanding of dispatch
and ActionType
head to ReduRx.
import 'package:flutter/material.dart' hide State;
import 'package:flutter_redurx/flutter_redurx.dart';
class State {
State({this.title, this.count});
final String title;
final int count;
}
class Increment extends Action<State> {
@override
State reduce(State state) =>
State(title: state.title, count: state.count + 1);
}
void main() {
final store =
Store<State>(State(title: 'Flutter-ReduRx Demo Title', count: 0));
runApp(Provider(store: store, child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter-ReduRx Demo',
theme: ThemeData(
primarySwatch: Colors.pink,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Connect<State, String>(
convert: (state) => state.title,
where: (prev, next) => next != prev,
builder: (title) => Text(title ?? ''),
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Connect<State, String>(
convert: (state) => state.count.toString(),
where: (prev, next) => next != prev,
builder: (count) => Text(count ?? '',
style: Theme.of(context).textTheme.display1),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => Provider.dispatch<State>(context, Increment()),
tooltip: 'Increment',
child: Icon(Icons.add),
));
}
}