Flutter状态管理(一)——框架对比及选择

10 篇文章 0 订阅
3 篇文章 0 订阅

Flutter状态框架对比及选择(一)

简介

随着业务需求的持续迭代,对于状态的管理就显得尤为重要,数据导向的页面更新是极有效的方式,但是业务越来越多就会导致各个module之间的依赖会越来越多。

这张图就反应了,当页面复杂时,如果全是有中央集权的状态控制就会显得杂乱无章,特别在定位问题时就会很头疼,还有一个很重要的原因是因为flutter在调试时报错会从runApp开始报,如果没有状态管理器输出对应的错误,很难定位是哪个数据问题造成的。

本次我们主要针对Flutter-Redux和Fish-Redux的使用方法和全局状态管理进行比较,帮助选择对应的状态管理框架。

flutter-redux

简介

flutter-redux,作为flutter官方插件,稳定性和后期维护的持续性都有所保障。在功能方面,对于Flutter原编程的方式并没有太大改变,只是对数据的管理和刷新进行了封装。

使用方法

1、在App层级添加全局Store

  final store = Store<CountState>(countReducer, initialState: CountState.initState());
  runApp(new MyApp(store));

2、创建State

@immutable
class CountState {
  final int _count;
  get count => _count;

  CountState(this._count);

  CountState.initState() : _count = 0;
}

3、创建Action

class CountAction {}

4、创建reducer

final countReducer = combineReducers<CountState>([
  TypedReducer<CountState, CountAction>(_incrementCount),
]);

CountState _incrementCount(CountState state, action) {
  return CountState(state.count + 1);
}

5、在页面中使用Connect进行state->viewModel的转化

Center(
        child: StoreConnector<CountState,int>(
          converter: (store) => store.state.count,
          builder: (context, count) {
            return Text(
              count.toString(),
              style: Theme.of(context).textTheme.display1,
            );
          },
        ),
      )

6、其他页面调用相同state

    Scaffold(
      appBar: AppBar(
        title: Text('Under Screen'),
      ),
      body: Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            StoreConnector<CountState,int>(
              converter: (store) => store.state.count,
              builder: (context, count) {
                return Text(
                  count.toString(),
                  style: Theme.of(context).textTheme.display1,
                );
              },
            ),
          ],
        ),
      ),
      floatingActionButton: StoreConnector<CountState,VoidCallback>(

        converter: (store) {
          return () => store.dispatch(CountAction());
        },
        builder: (context, callback) {
          return FloatingActionButton(
            onPressed: callback,
            child: Icon(Icons.add),
          );
        },
      ),
    )

7、是否更新页面

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Todo &&
          runtimeType == other.runtimeType &&
          complete == other.complete &&
          task == other.task &&
          note == other.note &&
          id == other.id;

最终结果

多页面状态共享,并且根据数据变化更新对应模块

fish-redux

简介

闲鱼出品,架构层级清晰,对于代码约束力度较强,适合大型项目

使用方式

(只针对flutter-redux的例子的全局state)

Widget fishReduxApp() {
  final AbstractRoutes routes = PageRoutes(
    pages: <String, Page<Object, dynamic>>{
      "top": FishReduxTestPage(),
      "next": FishReduxNextPage()
    },
    visitor: (String path, Page<Object, dynamic> page) {
      /// 只有特定的范围的 Page 才需要建立和 AppStore 的连接关系
      /// 满足 Page<T> ,T 是 GlobalBaseState 的子类
      if (page.isTypeof<GlobalBaseState>()) {
        /// 建立 AppStore 驱动 PageStore 的单向数据连接
        /// 1. 参数1 AppStore
        /// 2. 参数2 当 AppStore.state 变化时, PageStore.state 该如何变化
        page.connectExtraStore<GlobalCountState>(GlobalStore.store,
                (Object pagestate, GlobalCountState appState) {
              final FishReduxTestState p = pagestate;
              if (p.count != appState.count) {
                if (pagestate is Cloneable) {
                  final Object copy = pagestate.clone();
                  final FishReduxTestState newState = copy;
                  newState.count = appState.count;
                  return newState;
                }
              }
              return pagestate;
            });
      }});

  return MaterialApp(
    title: 'zhile_demo',
    debugShowCheckedModeBanner: false,
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: FishReduxTestPage().buildPage(null),
    onGenerateRoute: (RouteSettings settings) {
      return MaterialPageRoute<Object>(builder: (BuildContext context) {
        return routes.buildPage(settings.name, settings.arguments);
      });
    },
  );
}

该代码是全局store配置,fish-redux的针对此场景的实现原理是,mainStore不仅仅是自己的page绑定的store,还可以合成公共store,如下方代码,这个store就可以将多页面公用的store进行页面间的共用。相对于flutter-redux的实现,就会显得比较绕。

page.connectExtraStore<GlobalCountState>(GlobalStore.store,
                (Object pagestate, GlobalCountState appState) {
              final FishReduxTestState p = pagestate;
              if (p.count != appState.count) {
                if (pagestate is Cloneable) {
                  final Object copy = pagestate.clone();
                  final FishReduxTestState newState = copy;
                  newState.count = appState.count;
                  return newState;
                }
              }
              return pagestate;
            });
      }});

比较

flutter-redux优点

1、学习门槛低,侵入性小
2、多个页面共同使用一个State或者同一个Reducer时简单方便

flutter-redux缺点

由于没有Effect这个定义,在只修改逻辑方面或者其他不需要刷新页面的操作上,会不够方便。
使用后对代码的复杂性有提升,相较于fish-redux对代码结构的强制性较弱,导致大型项目代码维护成本较高

其他

判断是否更新

flutter-redux需要重写viewModel的==方法,确定返回的数据和当前的model是否相同,如果返回true表明不需要更新,false则更新。更新时view所使用的的将是新的viewModel。
而Fish-redux的做法是相同的,使用的是!identical(oldState, newState)来判断是否更新,并且state需要强制实现Cloneable接口,并且重写clone方法,保障在需要更新时更新数据并且保障原对象数据无误。

相比较而言各有优劣。flutter-redux思路清晰,更新后就是数据更新重新获取。fish-redux则更加纯粹,开发者只需要关注个体State即可。

个人看法

从实现上,flutter-redux的State更大,也更接近于Redux。fish-redux的State就会显得很灵活很小,可以针对各个模块,取代了viewmodel。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值