fish-redux(二):effect的使用

1. effect打印

上面的实例中并没用到effect,现在在effect代码中添加:

Effect buildEffect() {
  return combineEffects(>{
    Lifecycle.initState: _init,
    PageAction.update: _onUpdate,
  });
}

void _init(Action action, Context ctx) {
  println("Effect: _init");
}

void _onUpdate(Action action, Context ctx) {
  println("Effect: _onUpdate");
}

在Page中添加effect:

class MainPage extends Page> {

  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

点击按钮发现effect会响应,但reducer没有响应了,可见effect会比reducer优先收到action

I/flutter (17799): action:update
I/flutter (17799): Effect: _onUpdate

2. effect使用

下面修改fish-redux(一)中的代码,使用effect实现点击按钮弹出输入对话框来更新数据。

在PageAction中添加onEdit,一般触发effect的Action以onXXXX命名:

enum PageAction {onEdit, update}

class PageActionCreator {
  static Action updateAction(String title, String content) {
    println('action:update');
    return Action(
      PageAction.update,
      payload: {'title': title, 'content': content},
    );
  }

  static Action onEditAction() {
   return Action(PageAction.onEdit);
  }
}

view文件修改为点击按钮发送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监听了Lifecycle.initState和 PageAction.onEdit两个Action,_init方法内可以进行数据初始化,比如读取数据库等等,_init方法会在initState方法后调用。在_onEdit方法内实现弹窗动作,在数据回传后发送updateAction来更新页面数据。

Effect buildEffect() {
  return combineEffects(>{
    Lifecycle.initState: _init,
    PageAction.onEdit: _onEdit,
  });
}

void _init(Action action, Context ctx) {
  println("Effect: _init");
  ctx.dispatch(PageActionCreator.updateAction('title', 'init'));
}

String _input;


void _onEdit(Action action, Context ctx) {
  print('Effect _onEdit');
  showDialog(
      context: ctx.context,
      builder: (_) => new AlertDialog(
          title: Text("Modify content"),
          content: TextField(
            onChanged: (_){
              _input = _;
            },
          ),
          actions:[
            new FlatButton(child:new Text("CANCEL"), onPressed: (){
              Navigator.of(ctx.context).pop();
            },),
            new FlatButton(child:new Text("OK"), onPressed: (){
              Navigator.of(ctx.context).pop(_input);  //确定按钮关闭对话框携带数据
            },)
          ]
      )
  ).then((_){  //数据回传后通过updateAction更新页面数据
    ctx.dispatch(PageActionCreator.updateAction('title', _));
  });
}

点击按钮后发送onEditAction来触发Effect来执行弹窗动作,数据回传后通过updateAction来触发reducer更新页面数据

你可能感兴趣的:(fish-redux(二):effect的使用)