store的作用主要是对全局状态进行管理,但并不是每个组件或者页面都要使用它,只有真正使用到这个全局状态时,组件或者页面的state去implements就可以了。
创建Store
在lib下创建一个store的包,然后,我们拿app主题色为例:
这里,我们不是去写一个组件或者是一个页面,而是单纯的对状态进行管理,所以不需要专门使用插件进行生成。当然也可以插件生成,然后手动修改,看个人需要。
第一步,需要创建一个全局state,这个state中只有一个themeColor的属性(也可以多个,比如字体颜色、大小等)。--store/store.dart
import 'dart:ui';
import 'package:fish_redux/fish_redux.dart';
abstract class GlobalBaseState{
Color get themeColor;
set themeColor(Color color);
}
class GlobalState implements GlobalBaseState, Cloneable<GlobalState>{
@override
Color themeColor;
@override
GlobalState clone() {
return GlobalState();
}
}
这里我们创建了一个全局的状态--GlobalState,它是在抽象GlobalBaseState基础上创建的。
第二步,我们来创建管理这个全局状态的意图Action及针对这个意图的处理reducer。
--store/action.dart & store/reducer.dart
Action:
import 'package:fish_redux/fish_redux.dart';
enum GlobalAction { changeThemeColor }
class GlobalActionCreator{
static Action onChangeThemeColor(){
return const Action(GlobalAction.changeThemeColor);
}
}
定义这个意图名:changeThemeColor
然后处理reducer:
import 'package:fish_redux/fish_redux.dart';
import 'dart:ui';
import 'package:flutter/material.dart' hide Action;
import 'action.dart';
import 'state.dart';
Reducer<GlobalState> buildReducer(){
return asReducer(
<Object, Reducer<GlobalState>>{
GlobalAction.changeThemeColor: _onChangeThemeColor,
},
);
}
GlobalState _onChangeThemeColor(GlobalState state, Action action){
final Color color = state.themeColor == Colors.green ? Colors.blue : Colors.green;
return state.clone()..themeColor = color;
}
意图--Action changeThemeColor的具体处理实现:_onChangeThemeColor,切换主题色。
第三步我们就可以创建store。--store/store.dart
import 'package:fish_redux/fish_redux.dart';
import 'state.dart';
import 'reducer.dart';
class GlobalStore{
static Store<GlobalState> _globalStore;
static Store<GlobalState> get store =>
_globalStore ??= createStore<GlobalState>(GlobalState(), buildReducer());
}
GlobalStore创建需要GlobalState及reducer。
使用GlobalStore
首先,我们需要在入口处加一个页面的判断,判断页面的state有没有implements 全局的state,即:implements GlobalBaseState
import 'package:fish_demo/list/page.dart';
import 'package:fish_demo/splash/page.dart';
import 'package:fish_demo/store/state.dart';
import 'package:fish_demo/store/store.dart';
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart';
import 'entrance/page.dart';
import 'grid/page.dart';
Widget createApp(){
final AbstractRoutes routes = PageRoutes(
pages:<String,Page<Object,dynamic>>{
'splash_page':SplashPage(),
'entrance_page':EntrancePage(),
'grid_page':GridPage(),
'list_page':ListPage(),
} ,
//重点-----
visitor: (String path,Page<Object, dynamic> page){
if(page.isTypeof<GlobalBaseState>()){
page.connectExtraStore<GlobalState>(GlobalStore.store, (Object pageState,GlobalState appState){
final GlobalBaseState p = pageState;
if(p.themeColor !=appState.themeColor){
if(pageState is Cloneable){
final Object copy = pageState.clone();
final GlobalBaseState newState = copy;
newState.themeColor = appState.themeColor;
return newState;
}
}
return pageState;
});
}
},
);
然后,page中的使用就跟fish redux一样了,我们在触发处dispatch这个page下声明的相关意图给到effect,在effect中直接使用GlobalStore.store.dispatch给到全局状态的处理reducer进行处理。
当前page下action中声明,view组件中触发:
import 'package:fish_redux/fish_redux.dart';
//TODO replace with your own action
enum ItemAction { changeThemeColor }
static Action changeThemeColor(){
return const Action(ItemAction.changeThemeColor);
}
}
......
view中触发:
onTap: (){
dispatch(ItemActionCreator.changeThemeColor());
},
当前page下effect中直接处理:
import 'package:fish_demo/store/action.dart';
import 'package:fish_demo/store/store.dart';
import 'package:fish_redux/fish_redux.dart';
import 'action.dart';
import 'state.dart';
Effect<ItemState> buildEffect() {
return combineEffects(<Object, Effect<ItemState>>{
ItemAction.changeThemeColor: _onChangeThemeColor,
});
}
void _onChangeThemeColor(Action action,Context<ItemState> ctx){
//发送改变全局状态意图:
GlobalStore.store.dispatch(GlobalActionCreator.onChangeThemeColor());
}
这时,全局状态的reducer接收到GlobalAction.changeThemeColor就开始进行全局状态处理。即:调用 _onChangeThemeColor。store/reducer.dart
GlobalState _onChangeThemeColor(GlobalState state, Action action){
final Color color = state.themeColor == Colors.green ? Colors.blue : Colors.green;
return state.clone()..themeColor = color;
}
具体实现可参考对应demo:https://gitee.com/lagman/fish_redux_demo