Fish Redux 全局Store-AppRoute使用指南

在学习怎么使用AppRoute前,先了解下这几个问题,肯定这是不是你须要的前端

  1. 为何Redux.js和Vuex是全局Store?git

    前端的单页面应用愈来愈复杂,一个model变化会引发另一个model变化,又可能引发视图变化。Redux的三大原则,使state的变化可预测成为可能。其中第一条就是单一数据源,这体现了集中思想。应用维护一颗状态树,而数据变化驱动视图从新刷新。单一的状态树更方便数据的管理,因为生命周期和App一致,组件间数据也更方便传递分享(如登陆信息)。github

  2. 为何Fish Redux不是这样的?json

    Fish Redux一开始只支持Page级别Stroe是业务的客观诉求。Flutter做为一个新技术栈要用在一个上亿用户的闲鱼App中,须要风险控制和隔离,只能先改写一些页面,验证改进迭代再逐步替换。redux

  3. 我是否须要使用AppRoute?数组

    若是你的诉求和闲鱼同样,那选择的是高难度路线,须要在集中和分治间作长久斗争。建议使用HybridRoute能省点时间,也方便后续改造。否则,那就用AppRoute吧,充分享受Flutter和Redux带来的优越性。markdown

设计思想

做者添加了Route这一层,它的核心做用是产生一个Page,对应不一样场景,实现了三个具体的XXXRouteapp

/// Route 抽象类,只提供返回一个page的能力
abstract class AbstractRoutes {
  Widget buildPage(String path, dynamic arguments);
}

/// AppRoutes实现多page公用一个store,适合全新App使用
class AppRoutes<T> implements AbstractRoutes {
  final Map<String, Dependent<T>> pages;
  final PageStore<T> _store;
    ...
}

/// 一个page,一个store,适合部分页面改写flutter的App使用,如如今的闲鱼 
class PageRoutes implements AbstractRoutes {
  final Map<String, Page<Object, dynamic>> pages;
    ...
}

/// 混合Routes,能够同时使用AppRoutes和PageRoutes,适合都要的App,如将来一段时间的闲鱼
class HybridRoutes implements AbstractRoutes {
  final List<AbstractRoutes> routes;
    ...
}    
复制代码

使用方式

  1. 定义一个AppRoute框架

    /// app_route.dart
    /// 由于是全局的,这里用单例,也比较方便调用
    class AppRoute {
      static AbstractRoutes _global;
      static AbstractRoutes get global {
        if (_global == null) {
          _global = AppRoutes(preloadedState: AppState.initialState(), pages: {
            // 这里有两种写法,效果是同样的,带操做符的写法比较生动,也简短些。
            // RoutePath.todoList: TodoListPage().asDependent(TodoListConn()),
            RoutePath.todoList: TodoListConn() + TodoListPage(),
            RoutePath.todoDetail: TodoDetailConn() + TodoDetailPage(),
          });
        }
        return _global;
      }
    }
    
    /// 减小魔法字段,这些常量放在constant里也能够,放在这里只是方便。
    class RoutePath {
      static const String todoList = 'todo_list';
      static const String todoDetail = 'todo_detail';
    }
    复制代码
  2. 定义一个AppState,用来做为状态树的根节点ide

    /// screens/todo_list/state.dart
    class AppState implements Cloneable<AppState> {
      TodoListState todoListState;
      TodoDetailState todoDetailState;
    
      AppState(this.todoListState, this.todoDetailState);
    
      @override
      AppState clone() {
        return AppState(todoListState, todoDetailState);
      }
    
      AppState.initialState()
          : todoListState = initState(null),
            todoDetailState = TodoDetailState();
    }
    复制代码
  3. 定义Connect,描述subState和父State之间的转化关系

    /// screens/todo_list/state.dart
    /// get定义从大state取小state,set定义小state怎么改变大state
    class TodoListConn extends ConnOp<AppState, TodoListState> {
      @override
      TodoListState get(AppState state) => state.todoListState;
      
      @override
      void set(AppState state, TodoListState subState) =>
          state.todoListState = subState;
    }
    复制代码
  4. 替换原来Page产生的方式

    /// main.dart
    home: AppRoute.global.buildPage(RoutePath.todoList, null),
    复制代码
  5. 额外处理(有数据跳转的Page)

    /// screens/todo_detail/reducer.dart
    /// 页面跳转可能会有数据传递,好比list到detail页面,须要传递id,
    /// 这是很常见的,那数据何时传递?天然是page生成的时候,能够看到[AbstractRoutes]
    /// 的buildPage接受一个arguments参数,dynamic你能够传任意结构数据,推荐传Map,原生json样式
    /// 若是arguments不为null,Route会帮咱们发一个route的Action,
    /// 因此咱们须要在对应的Reducer里处理一下
    Reducer<TodoDetailState> buildReducer() {
      return asReducer<TodoDetailState>(<Object, Reducer<TodoDetailState>>{
        RouteAction.route: _route,
          ...
      });
    }
    
    /// 接到route Action,更新下state的id
    TodoDetailState _route(TodoDetailState state, Action action) {
      final TodoDetailState newState = state.clone();
      newState.id = action.payload['id'];
      return newState;
    }
    复制代码

对比体验Flutter Redux

一直以来Fish Redux和Flutter Redux的最佳实践并不一样,一个是Page级别的状态管理,一个是App级别状态管理,因此算是错位竞品。在Fish Redux加入Route后,它也算彻底体了,这两个都用事后我简单对比下:

  1. 方便度

    Flutter Redux调用简单,想要深刻理解API含义,会难一些。Fish Redux概念多,感受是把二维数组flat了,大堆的定义和概念,可能会劝退小部份没耐心的同窗。然而框架意图是清晰的,并且代码也有精心设计的痕迹。这点对我而言势均力敌。

  2. 文档例子

    Flutter Redux优胜,文档和例子都比刚开源的Fish Redux多不少,Fish Redux文档很少但都有中文版哦

  3. 问题响应

    Fish Redux优胜,Github上Issue基本能在12小时内获得做者或热心网友的回复和解答。而Flutter Redux的做者维护了不少个库,精力有限,因此Issue处理速度能够说是拖拖拉拉了

  4. 完备度

    功能上都是完备的,形式上Flutter Redux须要依赖两个库,Fish Redux没有任何其余三方依赖会好一点点

  5. 性能

    其实状态管理的初衷并不会很在乎性能,毕竟它只是个状态管理啊,管理都须要额外成本的。可是fish redux确实关注了并对于大列表场景作了比较突出的优化,性能提高刚刚的。

总结:Fish Redux彻底能够成为Flutter状态管理的备选方案了,并且它还正以肉眼可见的速度在成长。

后续

对比事后以为Fish Redux不错,想推销给长官

我:报告老板,ali的Fish Redux老NB了,咱们项目要不用这个吧?

老板:哪NB了?

我:巴拉巴拉~

老板:哪些大厂在用了

我:额,貌似就ali

老板:单元测试覆盖多少?

我:快50%吧

老板:性能提高多少,有benchmark吗?

我:。。。

抱歉,以上是我脑补的,但以我老板的专业度,这些问题必问。。。

本文源码地址:https://github.com/hyjfine/flutter_redux_sample/tree/fish-redux-route

(完)

@子路宇, 本文版权属于再惠研发团队,欢迎转载,转载请保留出处。

相关文章
相关标签/搜索