使用 Redux 在 Flutter鸿蒙next 中实现状态管理

在 Flutter 中进行状态管理是开发应用程序时的一个关键问题。Flutter 提供了多种解决方案来管理应用的状态,其中 Redux 是一种广泛使用且功能强大的状态管理库。虽然 Redux 最初是为 JavaScript 和 React 设计的,但它的核心概念非常适用于 Flutter,因此我们可以在 Flutter 中使用 Redux 来高效地管理应用的状态。

什么是 Redux?

Redux 是一个专注于“单一状态树”的状态管理模式。它通过三个核心原则来管理应用的状态:

  1. 单一数据源:应用的整个状态存储在一个全局的 store 中,而不是分散在各个组件中。
  2. 状态是只读的:唯一能改变状态的方式是触发一个“动作”(Action)。动作描述了事件的发生,但不直接修改状态。
  3. 使用纯函数来修改状态:状态的修改是通过 reducers 来完成的,reducer 是一个纯函数,它接收当前状态和动作,返回新的状态。

如何在 Flutter 中实现 Redux?

在 Flutter 中,使用 Redux 管理状态并不复杂,接下来,我们将从头开始实现一个简单的 Redux 状态管理。

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 reduxflutter_redux 依赖:

dependencies:flutter:sdk: flutterredux: ^5.0.0flutter_redux: ^0.6.0

2. 定义动作(Action)

在 Redux 中,动作是描述要执行什么操作的对象。在 Flutter 中,通常我们会为每个界面或者功能模块定义不同的动作。

例如,在一个计数器应用中,我们可能需要一个增加计数的动作:

class IncrementAction {}
class DecrementAction {}

3. 定义状态(State)

状态通常是一个包含所有需要管理的数据的对象。在我们的例子中,状态是一个简单的计数器:

class AppState {final int counter;AppState({required this.counter});// 用于创建初始状态factory AppState.initial() {return AppState(counter: 0);}// 返回新状态的副本AppState copyWith({int? counter}) {return AppState(counter: counter ?? this.counter);}
}

4. 定义 Reducer

Reducer 是一个纯函数,接收当前状态和一个动作,并返回一个新的状态。在这里,我们为 IncrementActionDecrementAction 定义了 reducer:

AppState appReducer(AppState state, dynamic action) {if (action is IncrementAction) {return state.copyWith(counter: state.counter + 1);} else if (action is DecrementAction) {return state.copyWith(counter: state.counter - 1);}return state;
}

5. 创建 Store

Store 是 Redux 中的核心,它持有应用的所有状态,并允许我们通过分发动作来更新状态。在 Flutter 中,我们可以使用 Store 类来创建 Redux Store:

final store = Store<AppState>(appReducer,initialState: AppState.initial(),
);

6. 将 Store 注入到应用中

使用 flutter_redux 库,我们可以将 Redux 的 Store 提供给整个应用。通过 StoreProvider,我们可以在任何需要访问 Store 的地方获取当前的应用状态。

class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return StoreProvider(store: store,child: MaterialApp(home: CounterPage(),),);}
}

7. 创建 UI 页面并连接 Store

在页面中,我们需要通过 StoreConnector 来访问 Redux 中的状态并分发动作。StoreConnector 使得我们能够直接从 Redux Store 中读取状态并触发更新。

class CounterPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return StoreConnector<AppState, _ViewModel>(converter: (store) => _ViewModel(counter: store.state.counter,onIncrement: () => store.dispatch(IncrementAction()),onDecrement: () => store.dispatch(DecrementAction()),),builder: (context, vm) {return Scaffold(appBar: AppBar(title: Text("Redux Counter")),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[Text('Counter: ${vm.counter}'),Row(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[ElevatedButton(onPressed: vm.onIncrement,child: Text("Increment"),),SizedBox(width: 20),ElevatedButton(onPressed: vm.onDecrement,child: Text("Decrement"),),],),],),),);},);}
}class _ViewModel {final int counter;final VoidCallback onIncrement;final VoidCallback onDecrement;_ViewModel({required this.counter, required this.onIncrement, required this.onDecrement});
}

8. 运行应用

通过上面的步骤,我们就已经将 Redux 成功集成到 Flutter 应用了。现在,应用中的状态将通过 Redux 进行集中管理,任何组件都可以通过分发动作来修改状态,且组件之间的状态管理将变得更加可预测和统一。

代码详细解释

  1. 动作(Action):在 Redux 中,动作是事件的描述。我们定义了两个简单的动作 IncrementActionDecrementAction 来增加和减少计数器的值。动作本身没有任何业务逻辑,只是一个标识符。

  2. 状态(State):状态是应用的数据存储。AppState 类包含了一个 counter 字段,用于存储当前的计数值。它还有一个 copyWith 方法,用于创建状态的副本并修改部分字段(这种不可变数据的操作在 Redux 中非常常见)。

  3. ReducerappReducer 是一个函数,接收当前的状态和一个动作,根据动作的类型来返回新的状态。它是 Redux 中的核心逻辑部分,通过纯函数来处理状态的变更,保证了状态更新的可预测性。

  4. StoreStore 是 Redux 的核心对象,它持有状态并允许我们通过 dispatch 来更新状态。通过将 store 传递给 StoreProvider,我们可以在整个应用中访问 Redux 存储的状态。

  5. StoreConnector 和 UI 连接StoreConnector 是 Flutter 中用于连接 Redux Store 和 UI 的组件。它通过 converter 属性将 Redux Store 的状态和更新方法转换为 UI 所需的 ViewModel,然后传递给 builder 属性的回调函数。通过这种方式,UI 可以通过 ViewModel 来访问状态和触发动作。

总结

Redux 是一种非常强大且灵活的状态管理方案,特别适合需要集中管理大量共享状态的应用。在 Flutter 中使用 Redux 能够让我们的状态管理更加简洁、可维护和可预测,特别是当应用的状态越来越复杂时,Redux 的优势更加突出。通过本文的步骤,你可以轻松地在 Flutter 中实现 Redux 状态管理,并掌握其核心概念。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/885492.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

032集——圆转多段线(Circle to Polyline)(CAD—C#二次开发入门)

CAD中圆可转为带有凸度的多段线以方便后期数据计算、处理&#xff0c;效果如下&#xff1a; 白色为圆&#xff0c;红色为转换后的多段线&#xff08;为区分&#xff0c;已手工偏移多段线&#xff09; public static void XX(){var curves Z.db.SelectEntities<Entity>…

【极客兔兔-Web框架Gee详解】Day2 上下文Context

文章目录 一、框架结构二、设计上下文(Context):day2-context/gee/context.go1. 设计Context必要性1.1 接口粒度过细:1.2 缺乏扩展性:2. 代码3. 优势三、路由(Router): day2-context/gee/router.go四、框架入口:day2-context/gee/gee.go1. 代码五、框架使用: day2-context/m…

HTB:Sightless[WriteUP]

目录 连接至HTB服务器并启动靶机 使用nmap对靶机TCP端口进行开放扫描 继续使用nmap对靶机开放的TCP端口进行脚本、服务扫描 首先尝试对靶机FTP服务进行匿名登录 使用curl访问靶机80端口 使用浏览器可以直接访问该域名 使用浏览器直接访问该子域 Getshell 横向移动 查…

Oracle视频基础1.4.4练习

1.4.4 [dbs] 删干净上次创建的bbk ll rm -f *dbf ll rm -f spfilebbk.ora clear ll创建bbk的pfile&#xff0c;准备对应的目录 ll strings spfilewilson.ora | more strings spfilewilson.ora > initbbk.ora :%s/wilson/bbk :%s/*\.//g :wq ll vi initbbk.ora####### 创…

【.NET 8 实战--孢子记账--从单体到微服务】--简易权限--角色可访问接口管理

咱们继续来编写孢子记账的简易权限&#xff0c;这篇文章中我们将编写角色可访问接口的管理API&#xff0c;同样我不会把完整的代码全都列出来&#xff0c;只会列出部分代码&#xff0c;其余代码我希望大家能自己手动编写&#xff0c;然后对比项目代码。废话不多说&#xff0c;开…

Monetico: 文本到图像合成的革命性变革

在人工智能和创意技术领域&#xff0c;Collov-Labs 推出了具有开创性的文本到图像合成模型 Monetico&#xff0c;它将彻底改变我们创建和可视化数字内容的方式。Monetico 是著名的 Meissonic 模型的有效再现&#xff0c;它提供了一种独特且易于使用的方法&#xff0c;可根据文本…

海康私有化视频平台EasyCVR视频分析设备平台流媒体协议RTMP、HTTP-FLV、HLS的简单对比

在当今的数字化世界中&#xff0c;视频流协议的选择对于确保流畅、高效的视频传输至关重要。随着互联网技术的快速发展&#xff0c;直播和视频点播服务已经成为人们日常生活中不可或缺的一部分。无论是安防监控、在线教育、远程会议还是娱乐直播&#xff0c;用户对于视频流的实…

Java多线程详解⑥(全程干货!!!)死锁 || 构成死锁的条件 || 死锁总结 || Java标准库的线程安全类

这里是Themberfue 在上一节中&#xff0c;我们介绍了线程安全问题&#xff0c;对锁的概念以及使用 在本节中&#xff0c;进入 "死锁" 的概念以及如何产生 "死锁" 死锁 一个线程&#xff0c;一把锁&#xff0c;同时加两把锁 要想进入死锁的介绍和概念&a…

适用于 Windows 11/10 电脑 的 13 个最佳文件恢复软件

如果您由于系统故障、硬件损坏、人为错误或病毒攻击而丢失了重要文件或文件夹。不用担心&#xff0c;因为我们随时为您提供帮助&#xff01;借助正确的文件恢复工具&#xff0c;您可以立即检索计算机上不同类型的文件。如果你有为您的文件创建备份&#xff0c;你不用担心&#…

> 甘晴void:课程资源免费下载

为进一步减少信息差&#xff0c;便利同学&#xff0c;我把部分重要课程的轨迹&#xff08;期中期末考卷、机考题、作业答案、代码、工程项目等&#xff09;上传至Github。网址链接如下&#xff1a; https://github.com/wolfvoid/HNU-resourses Github平台的优势是下载免费&am…

华为OD机试 - 求小球落地5次后所经历的路程和第5次反弹的高度 (Java 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题 点这里。 实战项目访问&#xff1a;http://javapub.net.cn/ 专栏导读 本专栏收录于 《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;E卷D卷A卷B卷C卷&#xff09;》 。 刷的越多&#xff0c;抽中的概率越大&…

uniapp—android原生插件开发(2原生插件开发)

本篇文章从实战角度出发&#xff0c;将UniApp集成新大陆PDA设备RFID的全过程分为四部曲&#xff0c;涵盖环境搭建、插件开发、AAR打包、项目引入和功能调试。通过这份教程&#xff0c;轻松应对安卓原生插件开发与打包需求&#xff01; ***环境问题移步至&#xff1a;uniapp—an…

【机器学习】强化学习(1)——强化学习原理浅析(区分强化学习、监督学习和启发式算法)

文章目录 强化学习介绍强化学习和监督学习比较监督学习强化学习 强化学习的数学和过程表达动作空间序列决策策略&#xff08;policy&#xff09;价值函数&#xff08;value function&#xff09;模型&#xff08;model&#xff09; 强化学习和启发式算法比较强化学习步骤代码走…

常见 HTTP 状态码分类和解释及服务端向前端返回响应时的最完整格式

目前开发的项目很大程度上是为明年的国产化做准备了&#xff0c;所以借这个机会把用了十年的自研系统全部重写&#xff0c;订立更严格的规范&#xff0c;本文记录一下返回格式及对应状态码。 常见 HTTP 状态码及解释 HTTP 状态码用于表示客户端请求的响应状态&#xff0c;它们…

深入理解JVM

文章目录 1. JVM内存区域划分2. JVM中类加载过程类加载&#xff08;1&#xff09;类加载的基本流程&#xff08;2&#xff09;双亲委派模型 《深入理解java虚拟机》 在这本书前&#xff0c;面试官对于JVM也不是很了解。 这本书主要还是写个一下开发 JVM 的人。 1. JVM内存区域…

启动软件是用例吗

沙亚雄 2020-8-13 14:06 潘老师&#xff0c;你好&#xff0c;最近读了您的软件方法&#xff0c;结合自己的项目发现始终有一个疑问&#xff1f;那就是启动软件算不算一个用例&#xff0c;因为软件在启动的时候一般都要实例化一些对象&#xff0c;读一些配置文件等等。那启动软…

Ubuntu22.04中使用CMake配置运行boost库示例程序

Ubuntu22.04中使用CMake配置运行boost库示例程序 boost是一个比较强大的C准标准库&#xff0c;里面有很多值得学习的东西&#xff0c;比较asio网络库可以用来编写C TCP客户端或者TCP服务端接收程序。本文主要讲解如何在Ubuntu22.04中使用Cmake配置boost库&#xff0c;以及运行…

指标+AI+BI:构建数据分析新范式丨2024袋鼠云秋季发布会回顾

10月30日&#xff0c;袋鼠云成功举办了以“AI驱动&#xff0c;数智未来”为主题的2024年秋季发布会。大会深度探讨了如何凭借 AI 实现新的飞跃&#xff0c;重塑企业的经营管理方式&#xff0c;加速数智化进程。 作为大会的重要环节之一&#xff0c;袋鼠云数栈产品经理潮汐带来了…

Windows配置NTP时间同步

Windows下实现NTP时间同步 1、Windows时间服务(W32Time)2、Windows 时间同步的工作原理3、配置和管理 Windows 时间同步3.1 命令行工具&#xff1a;w32tm3.2 控制面板中的设置 4. 高级设置&#xff08;Windows Server 环境&#xff09;5.调整时间同步的间隔5.1 通过组策略调整时…

系统安全第七次作业题目及答案

一、 1.RBAC0 RBAC1 RBAC2 RBAC3 2.属性 身份标识 3.接入访问控制 资源访问控制 网络端口和节点的访问控制 二、 1.B 2.A 3.ABE 4.BCD 5.ABC 三、 1. 答&#xff1a;基于属性的访问控制&#xff08;ABAC&#xff09;是通过对实体属性添加约束策略的方式实现主、客体之…