# 状态管理概览
无状态组件:是不可变的,这意味着它们的属性不能改变,所有的值都是最终的。
有状态组件:持有状态可能在Widget生命周期中发生变化。实现一个StatefulWidget至少需要两个类:一个StatefulWidget类,一个State类
Flutter中三种推荐的状态管理方案:
- Redux: redux,flutter_redux
- ScopedModel:scoped_model
- Bloc:bloc,flutter_bloc
前面的是方案,后面的是对应的pub.dev中的第三方包名。
# 前置知识
状态管理主要的目的是解决:组件间状态传递。在学习之前,扩展一些基础的知识。
# 安装第三方包
两种安装方式:
flutter pub add [package-name]
:直接安装最新的包- 在
pubspec.yaml
的dependencies
中添加对应的包与版本,再使用flutter pub get
安装;
说明:为了学习体验一致,建议使用第二种,以免由于版本带来的兼容性问题。
# 类及构造函数
定义类:
class Demo {
final int count;
// 定义构造函数
Demo(this.count)
}
可以在书写了final int count
之后,使用VSCode的快捷菜单创建:
即是如下的菜单:
其中的Demo(this.count)
是Dart中的语法糖,也可以如下进行定义:
class Demo {
int count = 0;
Demo(int count) {
this.count = count;
}
}
// 其中this.count中的this可以省略
class Demo {
int count = 0;
Demo(int count) {
count = count; // 这一行是不是看起来非常的多余,括号中的count是一个形参,是外部传递进来的,等号左边的count是Demo类中的公有成员。
}
}
上面的写法太多余了,所以推荐使用语法糖的写法:Demo(this.count)
# 命名式构造函数
class Demo {
final int count = 0;
Demo(this.count)
// 命名式构造函数
Demo.iniState() : count = 0;
}
# 可选参数与必传参数
class Demo {
final int count;
Demo(this.count);
}
这个地方的count就是一个必传参数:
可以省略new
关键字:
设置成可选参数:
注意:
设置成可选参数之后,需要通过属性名才能设置参数的值;
class Demo { final int? count; Demo({this.count}); } var demo = Demo(count: 0);
可以在申明的类型之后使用
?
来告诉dart的编译器这里是一个可选的属性,从而跳过null
值检查;class Demo { final int? count; Demo({this.count}); }
也可以添加一个
required
带表是必传参数:class Demo { final int count; Demo({required this.count}); }
# 应用场景与优缺点
# 1. Redux
优点
Redux允许集中管理一个状态,因为只有Reducers可以完成从一个状态到另一个状态的转换。 在流程中插入中间件的便利性也是一种优势。例如,如果需要不断地验证与服务器的连接性或跟踪活动。
缺点
一个单一的Store和一个巨大的State(如果你想坚持Redux的良好做法)。
在Reducer和MiddleWare的层面上,有太多的 "如果......那么 "的比较。
重建次数太多(每次State发生变化时)
应用场景:
- 熟悉React,Redux,有之前的Redux的概念的学习;
- state功能模块不多,并且页面中不需要高性能刷新:例如,用户认证、购物车、等......
不推荐使用的场景:
当你需要处理某个东西的多个实例,并且每个实例都有自己的状态时,我不推荐使用Redux。
# 2. ScopedModel
优点
- ScopedModel可以很容易地将Model和它的逻辑重组在一个位置。
- ScopedModel不需要任何Streams概念的知识,这使得初学者更容易实现。
- ScopedModel既可以用于全局逻辑,也可以用于局部逻辑。
- ScopedModel不限于State管理。
缺点
ScopedModel并没有提供任何方法让代码知道Model的哪个部分发生了变化,并导致ScopedModelDescendant被调用。
太多的(重新)构建。
每当一个Model通知它的监听器时,所有与该Model相关的东西都会重新构建(AnimatedBuilder, InheritedWidget...)。
需要使用外部软件包,但有可能随着软件包的发展而发生中断变化。
应用场景
- 当开发者对Streams不是很熟悉时
- 当模型不是太复杂时
不推荐使用的场景:
- 当应用程序出于性能考虑,需要减少构建次数时。
- 当一个应用程序需要精确地知道模型的哪一部分已经改变了。
# 3. BLoC
优点
- BLoC可以轻松地将业务逻辑重新组合到一个位置。
- BLoC可以很容易地精确确定任何变化的性质(通过其输出接口,基于流)。
- 由于使用了 StreamBuilder 小工具,BLoC 可以很容易地将(重新)构建的数量限制在最低限度。
- 流的使用是非常强大的,并打开了许多行动的大门(转换,独特,debounce...)。
- BLoCs可用于全局和局部逻辑。
- 基本BLoC不限于状态管理
- 不需要使用任何外部软件包。
缺点:
对于初学者来说,开始使用BLoC是比较困难的,因为它需要额外了解Flutter的实际工作方式。
应用场景:
几乎所有的场景都可以使用,分cubit与bloc
不推荐使用的场景:
- 单一的state,没有太多性能的需求,直接使用scoped_model即可
- 功能比较单一,父子页面传参,没有跨层级;
← 异步编程思想 状态管理方案-Redux →