flutter_rx 0.1.2
flutter_rx: ^0.1.2 copied to clipboard
A redux style state management library, loosely inspired by NgRx.
flutter_rx #
A redux style state management library, loosely inspired by NgRx as well as flutter_redux and redux.
Key concepts #
- Actions describe unique events that are dispatched from components and services.
- State changes are handled by pure functions called reducers that take the current state and the latest action to compute a new state.
- Selectors are pure functions used to select, derive and compose pieces of state.
- State is accessed with the Store, an observable of state and an observer of actions.
Diagram #
The following diagram represents the overall general flow of application state in Flutter Rx. [Flutter_Rx Diagram]
Usage #
Below is a counter app that uses Flutter Rx
import 'package:flutter/material.dart';
import 'package:flutter_rx/flutter_rx.dart';
// One simple action: Increment
// all actions should extends StoreAction
class Increment extends StoreAction {}
// The reducer, which takes the previous count and increments it in response
// to an Increment action.
int counterReducer(int state, dynamic action) {
if (action is Increment) {
return state + 1;
}
return state;
}
void main() {
// Create your store as a final variable in the main function
// or inside a State object.
Store<int> store = Store<int>(
initialState: 0,
reducer: counterReducer,
);
runApp(FlutterRxApp(
store: store,
));
}
class FlutterRxApp extends StatelessWidget {
final Store<int> store;
FlutterRxApp({Key key, this.store}) : super(key: key);
@override
Widget build(BuildContext context) {
// The StoreProvider should wrap your MaterialApp or WidgetsApp. This will
// ensure all routes have access to the store.
//
// StoreProvider is just an InheritedWidget
// This is the simplest way to provide your store to all ancestors,
// but you are free to use other means of doing so if it better suits your needs
return StoreProvider<int>(
// Pass the store to the StoreProvider so that any ancestor will have access.
store: store,
child: MaterialApp(
home: HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('FlutterRx Counter Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'You have pushed the button this many times:',
),
// The State is exposed as a stream which allows you to use
// widgets you are already familiar with like StreamBuilder
// to listen to the application state
//
// Every time the button is tapped, an action is dispatched and
// run through the reducer. After the reducer updates the state,
// a new value is added to the state causing the Widget to
// automatically rebuilt with the latest count.
StreamBuilder(
// Use the StoreProvider to get the store pass in the state
stream: StoreProvider.of<int>(context).state,
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
return Text(
snapshot.hasData ? snapshot.data.toString() : '',
style: Theme.of(context).textTheme.headline4,
);
},
),
],
),
),
floatingActionButton: FloatingActionButton(
// Use the StoreProvider to get the store and call the dispatch methed
// with the increment action
onPressed: () => StoreProvider.of<int>(context).dispatch(
Increment(),
),
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}