全局变量似乎是美妙的Flutter程序组件,因为它们只需声明一次,就可以被程序中的每个函数访问。然而,这些变量的成本比你想象的要高,主要是因为:
- 如果你删除了一个全局变量,你必须在整个程序中进行搜索,重构每一个可以访问被删除的全局变量的函数
- 它们很难测试,因为你必须在测试用例之间重置它们
- 由于每个函数都可以修改全局变量,所以很难跟踪变化。
上述所有原因说明了为什么在Flutter中不应该使用全局变量。在本教程中,我们将详细了解全局变量的缺点,并学习如何以更有效的方式来管理状态。
目录
什么是Flutter中的全局变量?
全局变量是公共变量,可以被Flutter程序中的每个方法和对象访问。
全局变量是局部变量的替代品,局部变量是在一个方法中创建的,并在该方法中被访问。
本地变量和全局变量的区别在于,本地变量不能被同一程序中的其他方法访问--因此,与全局变量相比,本地变量的范围有限。
在Flutter中使用全局变量的缺点
在Flutter中使用全局变量一直受到质疑和批评,通常被认为是不好的做法。以下是使用全局变量所带来的缺点。
复杂的代码维护过程
改变或删除一个全局变量会引发一系列连锁反应,因为使用该全局变量的小部件和方法都会受到影响。
如果你想改变一个全局变量,你必须分析访问全局变量的每个部件会受到怎样的影响,并进行具体和必要的修改。
如果你删除了一个全局变量,你必须在整个程序中进行搜索,并重构每个可以访问被删除的全局变量的函数。
全局变量使单元测试很痛苦
如果你改变了一个有全局变量的模块,那么你将不得不为接下来的测试重新设置它。
要理解使用全局变量的遗留代码是很难的,要了解程序流程是如何运作的就更难了。你很难有效地测试你不理解的代码,而且调试也很困难,因为你不知道谁改变了全局变量。
全局变量导致了意大利面条式的代码
由于程序中的每个函数都可以修改全局变量,所以很难跟踪变化。如果您正在构建一个大型应用程序,那么在Flutter中使用全局变量的情况就会升级。即使您正在构建小型 Flutter 应用程序,全局变量也是一种灾难。
全局变量反对封装
全局变量使得封装无法实现,封装是一个OOP概念,将代码包装成一个单元。封装使代码安全且易于维护。如果你想有效地使用封装,你必须禁止全局变量。
规范全局变量需要大量的纪律,因为它们会产生意大利面条般的代码。然而,有一些开发人员会使用全局变量,因为他们在一个小团队中,在某些情况下不利于改变。
但是,无论应用程序的规模如何,当需要维护代码时,全局变量会带来挑战。如果有必要使用全局变量,至少要让它们成为不可变的。
在下一节中,你将学习状态管理库和包,这些库和包提出了更好的管理变量状态的方式,而不会伤害到维护程序。
如何以更好的方式管理状态
Flutter是一个跨平台的动态框架,收集和处理来自用户的数据。
从开关到单选按钮,数据状态必须得到有效管理。然而,全局变量给应用程序的数据流增加了复杂性。全局变量使数据很容易发生突变,这可能会导致处理从用户那里收集到的数据时出现混乱。
状态管理包,如provider ,可以用来缓解全局变量带来的问题。下面是一个状态包管理和库的列表,你可以用它来管理状态。
提供者状态管理包
状况管理器 provider状态管理器包被广泛用于收集小组件的状态数据,并在状态改变时更新小组件。
当使用提供者时,在数据突变的情况下,只有受影响的小部件会被更新。与处处变化的全局变量相比,提供者降低了复杂性。提供者从widget收集数据,并监听widget周围发生的数据变化。
这个包将应用程序的状态与用户界面分开,provider ,促进应用程序的维护和测试。
使用下面的代码片断来添加和使用provider 包插件:
dependencies:
flutter:
sdk: flutter
provider: ^3.1.0
provider 包还允许你与多个类共享widget状态:
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => CartModel()),
Provider(create: (context) => SomeOtherClass()),
],
child: const MyApp(),
),
);
}
GetX
GetX是一个轻量级的Flutter库,它可以促进可扩展性,因为它允许你将视图、依赖注入、表现层和依赖注入解耦。
它提供了以下功能:
- 状态管理
- 依赖性注入
- 导航
- 路线管理
如果您正在寻找一个节约资源和消耗最小的库,GetX是最适合您的。
要在您的Flutter应用程序中开始使用GetX,请在您的pubspec.yaml文件中添加get 。
dependencies:
get:
接下来,导入使用GetX库函数和组件时需要的get 文件。
import 'package:get/get.dart';
Riverpod
Riverpod项目与provider 包类似 - 唯一的区别是它以单向方式分发数据。
这个状态管理器可以确保你的代码是可测试的,并且易于阅读,因为它消除了组合对象的嵌套。其特别之处在于它能在编译过程中检测出错误。这将节省你的时间,因为你将在运行时为你的应用程序增加缺陷之前修复错误。
Redux
Redux是一个库,可以帮助你有效地管理小部件的数据状态。Redux是一个架构,它以单向的方式执行跨部件的状态数据分配。这个库很好,因为它消除了状态的重复,你可以测试状态结果是否为真。
SetState 的方法
之前,我们只介绍了管理状态的Flutter包和库。
有一个叫做setState 的方法,当你的widget改变数据值时可以调用。它将导致UI根据新的状态而改变。你可以添加当状态改变时做一些事情的代码。这里是Flutter中setState 的一个基本实现。
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
_counter++;
setState(() {});
}
结语
在本教程中,我们已经详细了解了什么是全局变量,以及为什么我们不应该在Flutter中使用它们。此外,我们还探讨了各种状态管理库,你可以用来更有效地管理状态。