1. effect打印
上面的實例中并沒用到effect,現(xiàn)在在effect代碼中添加:
Effect<PageState> buildEffect() {
return combineEffects(<Object, Effect<PageState>>{
Lifecycle.initState: _init,
PageAction.update: _onUpdate,
});
}
void _init(Action action, Context<PageState> ctx) {
println("Effect: _init");
}
void _onUpdate(Action action, Context<PageState> ctx) {
println("Effect: _onUpdate");
}
在Page中添加effect:
class MainPage extends Page<PageState, Map<String, dynamic>> {
MainPage():super(
reducer: buildReducer(),
initState: initState,
view: buildView,
effect: buildEffect(),
);
}
重啟運行,打印如下:
I/flutter (17799): main
I/flutter (17799): Reducer:buildReducer
I/flutter (17799): state:initState
I/flutter (17799): Effect: _init
I/flutter (17799): view:buildView
點擊按鈕發(fā)現(xiàn)effect會響應(yīng),但reducer沒有響應(yīng)了,可見effect會比reducer優(yōu)先收到action
I/flutter (17799): action:update
I/flutter (17799): Effect: _onUpdate
2. effect使用
下面修改fish-redux(一)中的代碼,使用effect實現(xiàn)點擊按鈕彈出輸入對話框來更新數(shù)據(jù)。
在PageAction中添加onEdit,一般觸發(fā)effect的Action以onXXXX命名:
enum PageAction {onEdit, update}
class PageActionCreator {
static Action updateAction(String title, String content) {
println('action:update');
return Action(
PageAction.update,
payload: <String, String>{'title': title, 'content': content},
);
}
static Action onEditAction() {
return Action(PageAction.onEdit);
}
}
view文件修改為點擊按鈕發(fā)送onEditAction。
Widget buildView(PageState state, Dispatch dispatch, ViewService viewService) {
println('view:buildView');
return Scaffold(
appBar: AppBar(title: Text(state.title)),
body: Center(child: Text(state.content),),
floatingActionButton: FloatingActionButton(
onPressed: (){dispatch(PageActionCreator.onEditAction());},
child: Icon(Icons.edit),
),
);
}
添加Effect文件,這里Effect監(jiān)聽了Lifecycle.initState和 PageAction.onEdit兩個Action,_init方法內(nèi)可以進行數(shù)據(jù)初始化,比如讀取數(shù)據(jù)庫等等,_init方法會在initState方法后調(diào)用。在_onEdit方法內(nèi)實現(xiàn)彈窗動作,在數(shù)據(jù)回傳后發(fā)送updateAction來更新頁面數(shù)據(jù)。
Effect<PageState> buildEffect() {
return combineEffects(<Object, Effect<PageState>>{
Lifecycle.initState: _init,
PageAction.onEdit: _onEdit,
});
}
void _init(Action action, Context<PageState> ctx) {
println("Effect: _init");
ctx.dispatch(PageActionCreator.updateAction('title', 'init'));
}
String _input;
void _onEdit(Action action, Context<PageState> ctx) {
print('Effect _onEdit');
showDialog(
context: ctx.context,
builder: (_) => new AlertDialog(
title: Text("Modify content"),
content: TextField(
onChanged: (_){
_input = _;
},
),
actions:<Widget>[
new FlatButton(child:new Text("CANCEL"), onPressed: (){
Navigator.of(ctx.context).pop();
},),
new FlatButton(child:new Text("OK"), onPressed: (){
Navigator.of(ctx.context).pop<String>(_input); //確定按鈕關(guān)閉對話框攜帶數(shù)據(jù)
},)
]
)
).then((_){ //數(shù)據(jù)回傳后通過updateAction更新頁面數(shù)據(jù)
ctx.dispatch(PageActionCreator.updateAction('title', _));
});
}
點擊按鈕后發(fā)送onEditAction來觸發(fā)Effect來執(zhí)行彈窗動作,數(shù)據(jù)回傳后通過updateAction來觸發(fā)reducer更新頁面數(shù)據(jù)