The bar is fine and let go
Redux is a global state management plug-in, but it can also solve the problem of build calls after setState;
- There is a question here, Redux is passed in at the top level, so is it also performance expensive to go through layers to find this value;
SetState and story
SetState rerenders the entire page each time it is used
// In a template project created with flutter create
// We add a print to the Widget build of _MyHomePageState
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
// You'll notice that every time you click the hover button it prints' Build Runing? '
print('build runing ? ');
return Scaffold(...
);
}
}
void _increment() {
setState(){
// This thing is executed every time
// Flutter should be re-built
// A small amount of data is ok
// If there is a large amount of data, this is definitely a nightmare
_counter ++
}
}
Copy the code
I didn’t know how to solve this problem at first, so I thought I’d try Redux first
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^ 1.0.2
flutter_redux: ^ 0.7.0
Copy the code
then
/ / define the store
class AppStore {
int count = 0;
AppStore.initCount() {
this.count = 0;
}
AppStore(this.count);
}
/ / define the actions
enum AppActions { Increment }
/ / define reducer
AppStore reducer(AppStore store, dynamic actions) {
print('store runing reducer');
switch (actions['type']) {
case AppActions.Increment:
// define count++ as _increment
store.count++;
return store;
default:
returnstore; }}Copy the code
The top-level entry passes into Store
void main() {
// Initialize the store
final Store store =
Store<AppStore>(reducer, initialState: AppStore.initCount());
// Store should be placed at the top level of the application
runApp(MyApp(store: store));
}
Copy the code
StoreProvider parcel MaterialApp
class MyApp extends StatelessWidget {
final Store<AppStore> store;
const MyApp({Key key, this.store}) : super(key: key);
@override
Widget build(BuildContext context) {
// The top layer of the entire application is StoreProvider
return StoreProvider(
store: store,
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'))); }}Copy the code
Modify floatingActionButton Widget
// Use the reducer in the store
floatingActionButton: StoreConnector<AppStore, Function> (// Note the arrow function here
// dispatch Called the reducer
// The argument is action, which defines the action type as dynamic
// So it is theoretically possible to pass in any value
// But I'm used to using the map type
// Two keys can be defined in the map
// Action is a type of action
// One is data, which is the data to be passed in
// In flutter_redux, the return value of converter is the second argument to builder
// This parameter can be state or reducer
converter: (store) => () => store.dispatch({
"type": AppActions.Increment, /*"data":""*/
}),
builder: (context, callback) {
return FloatingActionButton(
onPressed: callback,
tooltip: 'Increment',
child: Icon(Icons.add),
);
}),
Copy the code
Modify Text Widget:
/ / use store. State. The count
// Notice the type
,>
StoreConnector<AppStore, String>(converter: (store) {
return store.state.count.toString();
},
builder: (context, count) {
return Text(
'$count',
style: Theme.of(context).textTheme.headline4,
);
}),
Copy the code
Print (‘store runing reducer’);
Then you’ll notice that build no longer prints