使用 redux 管理 flutter 应用数据

栏目: 服务器 · 发布时间: 6年前

内容简介:本文发布在最近在学 flutter,边学边记录了一本

本文发布在 使用 redux 管理 flutter 应用数据 ,后续一直会更新,感兴趣的可以关注一下。

最近在学 flutter,边学边记录了一本 写给前端看的 flutter 笔记 ,感兴趣的小伙伴可以一起来完善他。

使用 redux 管理 flutter 应用数据

redux 是什么?简单来说,就是为了解决 UI 层状态管理的方案,如果不熟悉,请先看文档学习一下,今天的重点不是学习 redux,而是直接用 redux 管理 flutter 的状态。

和 react 的比较

首先,flutter 和 react 真的太像了,连状态管理都有 redux 方案:

flutter react
redux.dart redux
flutter_redux react-redux
redux_thunk redux-thunk

另外,甚至还有 redux-epics 能够搭配 rxdart 对标 redux-observable 。对于 rxjs 熟悉的人应该也能够很快地开始 rxdart 了,再次证明知识是相似的,技能也是能够越学越快的。

为了不混淆大家,接下来我把 react 中的 redux 称为 react/redux , flutter 中的 redux 称为 flutter/redux

正题

现在我们用 flutter 写一个简单的 redux 例子:

使用 redux 管理 flutter 应用数据

完整代码在 https://github.com/riskers/flutter_notebook_redux ,有过 redux 经验的应该能看明白。使用到了:

  • redux
  • flutter_redux
  • redux_thunk

项目架构完全是之前按照我之前在 React 中的 经验 来做的

有几点需要注意:

  1. 初始化 Store

为了方便,可以在 state 中以一个 静态方法初始化 :

static AppState initialState() {
  return AppState(
    count: 0,
    clickCount: 0,
  );
}

然后在入口文件中 调用 :

final store = Store<AppState>(
  reducers,
  middleware: [thunkMiddleware],
  initialState: AppState.initialState(),  // 调用
);
  1. reducer 复制对象的方法

在 react/redux 中我们习惯这样写 reducer:

const reducer = (state={
  loading: false,
  data: [],
}, action) => {
  switch(action.type) {
    case CONST.FETCH_GITHUB_SEARCH_USER_LOADING:
      return {
        ...state,
        loading: true
      }
    case CONST.FETCH_GITHUB_SEARCH_USER_SUCCESS:
      return {
        loading: false,
        data: action.payload.items
      }
    default:
      return state
  }
}

重点是 ...state 这样的解构写法,实际是浅复制了 state 对象,而在 dart 中没有这么方便的方法,比如 reducers.dart 中的 copyWith :

AppState counterReducer(AppState state, dynamic action) {
  switch (action) {
    case INCREMENT:
      return state.copyWith(count: state.count + 1);
    case DECREMENT:
      return state.copyWith(count: state.count - 1);
  }

  return state;
}

copyWith 是我们自己写的 扩展 方法:

AppState copyWith({count, clickCount}) {
  return AppState(
    count: count ?? this.count,
    clickCount: clickCount ?? this.clickCount,
  );
}

??条件表达式count: count ?? this.count 表示 copyWith 只要没传进来 count 就把 AppState 实例的 count 值赋给 count,然后再实例化一个 AppState 对象。

参见其他的 复制对象的方案

  1. actions

比较有特点的就是 redux_thunk 的异步 action 写法:

ThunkAction asyncIncrement() {
  return (Store store) async {
    await Future.delayed(Duration(seconds: 3)); // 延迟 3 秒

    store.dispatch(INCREMENT);
  };
}

async / await 是不是很熟悉?

  1. StoreProvider / StoreConnector

StoreProvider 很简单,就是在根组件中挂载 store:

@override
Widget build(BuildContext context) {
  return StoreProvider<AppState>(
    store: store,
    child: MaterialApp(
      theme: ThemeData.dark(),
      home: Home(),
    ),
  );
}

而 StoreConnector 就比较麻烦了,需要先定义一个 ViewModel:

class AppStateViewModel {
  final AppState state;
  final void Function() onClick;

  AppStateViewModel({
    this.state,
    this.onClick,
  });
}

ViewModel 中规定你要在这个组件中使用的 Store 中的数据

class AddButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StoreConnector<AppState, AppStateViewModel>(
      converter: (store) {
        return AppStateViewModel(onClick: () {
          store.dispatch(INCREMENT);
          store.dispatch(CLICK);
        });
      },
      builder: (context, vm) {
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: FloatingActionButton(
            onPressed: vm.onClick,  // trigger!
            tooltip: 'Increment',
            child: Icon(Icons.exposure_plus_1),
          ),
        );
      },
    );
  }
}

StoreConnector 有两个方法:

  • converter : 使用给定的转换器函数将存储转换为 ViewModel,并将 ViewModel 传递给 builder 函数
  • builder : 承接 converter 返回的数据来使用

以 AddButton 组件为例,converter 返回 onClick 函数来触发 dispatch, builder 承接到这个函数,这样就能在发起 dispatch,走 redux 的流程了。

本文只介绍 redux 在 flutter 中的应用,如果你对 React 很熟,你应该能明白 redux 的意义,除了有个全局 store 外,深层组件之间通信也不是问题了,对于 flutter 这种框架也是很有意义的。

当然,数据管理方案上直接使用 redux 可能会比较重,这和 react 是类似的,小应用的话可以用全局事件来处理。但是,多人协作的大项目 redux 是你最应该想到的数据管理方案。

向我捐助 | 关于我 | 工作机会


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Haskell

Haskell

Simon Thompson / Addison-Wesley / 1999-3-16 / GBP 40.99

The second edition of Haskell: The Craft of Functional Programming is essential reading for beginners to functional programming and newcomers to the Haskell programming language. The emphasis is on th......一起来看看 《Haskell》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具