fish redux

本分主要介绍闲鱼出品的fish redux基础知识和使用,后续会有复杂应用场景分享。

flutter自带demo
void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(home: MyHomePage(title: 'Flutter Demo Home Page'),debugShowCheckedModeBanner: false,);}
}class MyHomePage extends StatefulWidget {MyHomePage({Key key, this.title}) : super(key: key);final String title;@override_MyHomePageState createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {int _counter = 0;void _incrementCounter() {setState(() {_counter++;});}@overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[Text('$_counter'),],),),floatingActionButton: FloatingActionButton(onPressed: _incrementCounter,tooltip: 'Increment',child: Icon(Icons.add),),);}
}

flutter的计数demo,方便后面对比。

redux

简介Redux的流程

简单说就是用户操作dispatcher(action),到reducer中处理相关数据和逻辑,存储数据到store中,更新state,触发UI刷新。

fish redux

部分重要概念

  1. component
    对局部的展示和功能的封装。对功能细分为修改数据的功能(Reducer)和非修改数据的功能(副作用Effect)。于是有了View、Effect、Reducer组件三要素。
  2. action
  • Action 包含两个字段

    • type
    • payload
  • 推荐的写法是
    • 为一个组件|适配器创建一个 action.dart 文件,包含两个类

      • 为 type 字段起一个枚举类
      • 为 Action 的创建起一个 ActionCreator 类,这样利于约束 payload 的类型。
    • Effect 接受处理的 Action,以 on{Verb} 命名
    • Reducer 接受处理的 Action,以{verb} 命名
    • 示例代码
enum MessageAction {onShare,shared,
}class MessageActionCreator {static Action onShare(Map<String, Object> payload) {return Action(MessageAction.onShare, payload: payload);}static Action shared() {return const Action(MessageAction.shared);}
}
  1. reducer
  • Reducer 是一个上下文无关的 pure function。它接收下面的参数

    • T state
    • Action action
  • 它主要包含三方面的信息
    • 接收一个“意图”, 做出数据修改
    • 如果要修改数据,需要创建一份新的拷贝,修改在拷贝上。
    • 如果数据修改了,它会自动触发 State 的层层数据的拷贝,再以扁平化方式通知组件刷新。
  • 示例代码
Reducer<String> buildMessageReducer() {return asReducer(<Object, Reducer<String>>{'shared': _shared,});
}String _shared(String msg, Action action) {return '$msg [shared]';
}class MessageComponent extends Component<String> {MessageComponent(): super(view: buildMessageView,effect: buildEffect(),reducer: buildMessageReducer(),);
}
  1. effect
    接收View的"意图",也包括对生命周期的回调。不修改数据,它对数据是只读的,如果要修改,应该发送一个Action到Reducer中去处理
cunter fish redux 版

基础目录
> -action.dart
> -effect.dart(本例中非必须)
> -page.dart
> -reducer.dart
> -state.dart
> -view.dart

action.dart

enum CounterAction { add, onAdd }class CounterActionCreator {//reducer使用static Action add() {return const Action(CounterAction.add);}//effect使用static Action onAdd() {return const Action(CounterAction.onAdd);}
}

state.dart

class CounterState implements Cloneable<CounterState> {int count = 0;@overrideCounterState clone() {return CounterState()..count = count;}
}CounterState initState(Map<String, dynamic> args){//什么也没做,只是初始化数据return CounterState();
}

reducer.dart

Reducer<CounterState> buildReducer() {return asReducer<CounterState>(<Object, Reducer<CounterState>>{CounterAction.add: _add,});
}CounterState _add(CounterState state, Action action) {final CounterState newState = state.clone();newState.count = ++state.count;return newState;
}

effect.dart

Effect<CounterState> buildEffect() {return combineEffects(<Object, Effect<CounterState>>{CounterAction.onAdd: _onAdd,});
}void _onAdd(Action action, Context<CounterState> ctx) {print("_onAdd");ctx.dispatch(CounterActionCreator.add());
}

view.dart

Widget buildView(CounterState state, Dispatch dispatch, ViewService viewService) {return Scaffold(appBar: AppBar(title: Text('CounterFishRedux'),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[Text(state.count.toString(),)],),),floatingActionButton: FloatingActionButton(//发送的action到了Effect中处理onPressed: () => dispatch(CounterActionCreator.onAdd()),//也可以发action到reducer中处理//onPressed: () => dispatch(CounterActionCreator.add()),tooltip: 'add',child: Icon(Icons.add),),);
}

page.dart

class CounterFishReduxPage extends Page<CounterState, Map<String, dynamic>> {CounterFishReduxPage(): super(initState: initState,effect: buildEffect(),reducer: buildReducer(),view: buildView,);
}

​ 在view.dart中,用户触发FloatingActionButton的onPress事件,dispatch了名为onAdd的Action,在effect.dart中接收到action,会继续dispatch,到reducer.dart中(这一步非必须,可以直接dispatch到reducer.dart中),在reducer.dart中,在state中取出state中的数据,处理(加一)后,返回state,数据更新到store中,触发UI更新,最终到view.dart中state中的数据会更新,取出新的数据显示。

​ fish redux适用于中大型项目,这种简单的功能直接用官方的setState即可。

​ 这样就可以单独作为一个page或者component使用,没有逻辑和UI的耦合。

更多更新关注微信公众号“Flutter入门” 知乎专栏同名

Flutter fish redux入门相关推荐

  1. 阿里宣布开源Flutter应用框架Fish Redux!

    3月5日,闲鱼宣布在GitHub上开源Fish Redux,Fish Redux是一个基于 Redux 数据管理的组装式 flutter 应用框架, 特别适用于构建中大型的复杂应用,它最显著的特征是 ...

  2. 阿里开源组装式 Flutter 应用框架 Fish Redux

    近日,阿里开源了其 Flutter 应用框架 Fish Redux. Fish Redux 是一个基于 Redux 数据管理的组装式 Flutter 应用框架,它特别适用于构建中大型的复杂应用. 特性 ...

  3. 即将开源 | 2亿用户背后的Flutter应用框架Fish Redux

    2019独角兽企业重金招聘Python工程师标准>>> 背景 在闲鱼深度使用 Flutter 开发过程中,我们遇到了业务代码耦合严重,代码可维护性糟糕,如入泥泞.对于闲鱼这样的负责业 ...

  4. 刚刚,阿里宣布开源Flutter应用框架Fish Redux!

    3月5日,闲鱼宣布在GitHub上开源Fish Redux,Fish Redux是一个基于 Redux 数据管理的组装式 flutter 应用框架, 特别适用于构建中大型的复杂应用,它最显著的特征是 ...

  5. 2亿用户背后的Flutter应用框架Fish Redux

    背景 在闲鱼深度使用 Flutter 开发过程中,我们遇到了业务代码耦合严重,代码可维护性糟糕,如入泥泞.对于闲鱼这样的负责业务场景,我们需要一个统一的应用框架来摆脱当下的开发困境,而这也是 Flut ...

  6. 即将开源 | 2亿用户背后的Flutter应用框架Fish Redux 1

    背景 在闲鱼深度使用 Flutter 开发过程中,我们遇到了业务代码耦合严重,代码可维护性糟糕,如入泥泞.对于闲鱼这样的负责业务场景,我们需要一个统一的应用框架来摆脱当下的开发困境,而这也是 Flut ...

  7. Fish Redux 使用指南

    为啥要使用Fish redux 1,年前就被闲鱼大佬安利,种草已久 2,想要对比Flutter Redux,学习体会它带来的优越性 3,参与并支持一下国产,现在Flutter生态还在早期 准备工作 1 ...

  8. Fish Redux系列学习之认识effect、reducer

    继续前面两篇文章: Fish Redux系列学习之初探 Fish Redux系列学习之新建page以及认识state Fish Redux系列学习之认识view.action 这次我们学习剩下的两个e ...

  9. redux 入门到实践

    前言 之前没太理解redux,在使用时总是照葫芦画瓢,看项目里别人如何使用,自己就如何使用,这一次彻底学习了下官方文档,记录. 在学习redux初时,有三个概念需要了解. action reducer ...

最新文章

  1. Neumorphism.io一个神奇的网站,满足各种圆角矩形ICON图表立体化效果要求,这种样式的名称——新拟态
  2. SLAM后端优化中卡尔曼滤波的直观通俗解释
  3. jdk动态代理和cglib动态代理的区别
  4. mesos-dns marathon-lb
  5. 点击调用ajax,jQuery ajax在点击时调用,仅工作一次
  6. php 继承内核中的基类,php – 从基类调用继承类的父方法
  7. boost::intrusive::any_base_hook用法的测试程序
  8. 云计算将使IT人失业?惠普推云计算裁员九千!程序员如何面对即将到来的产业大调整?...
  9. C#入门,基本的整型输入
  10. 使用 vscode将本地项目上传到github、从github克隆项目以及删除github上的某个文件夹...
  11. java获取文件中的行号_如何取的Java源代码文件中文件名和行号
  12. [开源 .NET 跨平台 Crawler 数据采集 爬虫框架: DotnetSpider] [三] 配置式爬虫
  13. 村上隆取消NFT拍卖:会做更充分的准备,坚信NFT的巨大潜力
  14. 首批 8 款 5G 手机获 3C 认证;iPhone6 系列停产;Android Q Beta 5 发布 | 极客头条
  15. ASP.NET MVC5+EF6+EasyUI 后台管理系统(27)-权限管理系统-分配用户给角色
  16. linux测试sata硬盘读写速度
  17. 前端UI配色辅助RGB颜色调色板配色表HTML源码
  18. hibernate无法自动建表:ERROR: HHH000388
  19. 安卓设备设置 orientation 最简单的方法
  20. ChatGpt会替代码农可行性分析

热门文章

  1. 计算机网络—学习笔记
  2. Autodesk Inventor Routed Systems: Harness Autodesk Inventor Routed Systems: Harness Lynda课程中文字幕
  3. CANoe.DiVa 操作指南 - 预期响应设置
  4. CANoe.DiVa操作指南——配置特定测试序列
  5. mysql 覆盖写入_INSERT ON CONFLICT覆盖写入
  6. JS 的cookie三部曲
  7. Retrofit2.0初始化
  8. HOG(histogram of oriented gradients)特征个人总结
  9. Discuz!NT 代码阅读笔记(8)--DNT的几个分页存储过程解析
  10. Oracle 表创建和表管理