必看,使用Provider优雅解决Riverpod的参数依赖

Flutter _ 状态管理特别篇 —— Provide 自从上次写完状态管理拓展篇Rxdart之后断更了三个月。总结篇迟迟没有出来,在这里先说一声抱歉。对于我来讲状态管理这个本身就是一个新鲜玩意,所以在没有经过大型应用实战检验的总结都是空谈。这也是为什么我迟迟没有开始写总结篇的原因。不过在这我可以说一些自己的感受,供大家参考。在这几个月中,我用的比较多的是BLoC,它组织数据确实非常灵活,可以很轻松的实现懒加载之类的操作。而且stateful widget写的是越来越少了。 阅读详情

上一篇文章详细说明了状态管理在开发中的位置和所依赖的基础方法,帧与帧之间的变化是对应状态变化的体现,但每个框架都有其侧重点,Getx侧重简单,简单的页面,简单的状态管理,相对应的是复杂参数, 以及依赖传递时非常臃肿,需要使用很多Listen来同步不同的状态。Bloc有完整的filter,状态转移的监听,非常适合编辑器等复杂状态,例如回退操作,这两者一个适合简单业务,一个适合复杂协同业务,大多数项目都没有那么极端,所以Flutter官方推荐了Riverpod作为首推的状态管理工具。

具体对比请移步 一篇文章,告别Flutter状态管理争论,问题和解决

任何工具都有缺点,与此同时,就会有一个或者丑陋,或者优雅的Work around级别的解决方案,riverpod也是,这篇文章试图解决riverpod丑陋的参数传递问题。例如: 如下场景,一个日程任务有多种来源和多个视图才能确定某条任务, 我们假定参数为来源日期,来源计划,来源看板,那我们定位这一条任务就需要如下代码

/// 声明状态,需要三个入参

class TaskDetail extends _$TaskDetail {
  
  TaskModel build(int taskId, int planId, int viewId) {
    return service.query(taskId, planId, viewId);
  }
}
/// 使用需要明确的三个参数
class TaskDetailScreen extends HookConsumerWidget {
  final int taskId;
  final int planId;
  final int viewId;

  const TaskDetailScreen({
    super.key,
    required this.taskId,
    required this.planId,
    required this.viewId,
  });

  
  Widget build(BuildContext context, WidgetRef ref) {
    final taskModel = ref.watch(taskDetailProvider(taskId, planId, viewId));
    return Container();
  }
}

目前为止这段代码没有体现出任何的缺点,反而做到了状态的声明和使用的分离, 对于简单到中等复杂页面,这非常友好,如果我们选择使用非组件化,将所有代码写到这个TaskDetailScreen那将没有任何问题。因为不涉及参数传递或者指针(notifier)传递。但实际复杂的项目中,通常可重用和可阅读也是很重要的指标,这个时候我们不得不考虑使用组件来提升这两个属性。例如:我们有一个富文本组件, 如果我们只有简单的交互,我们可以通过传递taskModel或者增加Callback(String)等方法,与provider进行交互,但这通常会写成如下代码。

/// 需要透传参数或者notifer, 或者抛出Callback
class RichEditor extends ConsumerWidget {
  final int taskId;
  final int planId;
  final int viewId;

  const RichEditor({
    super.key,
    required this.taskId,
    required this.planId,
    required this.viewId,
  });

  
  Widget build(BuildContext context, WidgetRef ref) {
    return GestureDetector(
      onTap: () => ref.read(taskDetailProvider(taskId, planId, viewId).notifier).saveContent('content'),
      child: Text('editor'),
    );
  }
}

这是非常丑陋的,虽然这种情况在使用Bloc时会被非常优雅的解决,但也可以通过一些结合来尝试解决中等复杂难度的场景。

分析痛点和难点

riverpod在这个场景下的痛点时需要透传参数,且组件化时非常丑陋,容易出错,那他的难点在于什么?在于全局的Scope, 所有全局的管理,例如Getx等都会面临多个层级重复页面,多参数的在同一个路由栈这样常见的问题,或者同时显示多个相同组件(同一个provider)。难点在于无法隔离,也就是跟Context关联,局部状态。

找到难点,我们就可以从这个点出发去尝试解决这个问题,或者是这种特定用例下的问题,在不脱离riverpod的情况下,我们的直观选择是在局部使用ProviderScope, 例如:

 ProviderScope(overrides: [
      sharedPrefsProvider.overrideWithValue(sharedPrefs),
    ], child: const TaskDetailScreen()),

这是一种方案,但这种不符合riverpod的最佳实践,也容易造成状态管理的混乱,第二种方案是将参数使用其它方式进行Context相关的关联,比如通过自定义的InheritedWidget 这种方案类似于ThemeData的局部化处理,这种方案理解简单,但需要不同的页面和不同的Provider定制化, 第二种方案明显也丑陋的,虽然解决了部分问题, 但需要引入自定义的Scope。

组合Hook?

我们知道Riverpod是状态分离的,也就是声明和管理和使用状态是完全分离的,所以一个简单好用的界面内状态就可以极大简化这种类型的状态处理。所以,Flutter Hook就完美的补充了这部分。例如

final calendarFormat = useState(CalendarFormat.week);

TableCalendar(
          calendarFormat: calendarFormat.value,
          onFormatChanged: (format) {
            if (format != calendarFormat.value) {
              calendarFormat.value = format;
            }
          },
        ),

这里状态只和页面有关,声明、使用、 修改 都在一个build函数中完成,所以使用注解riverpod是有一点冗余的。本以为可以像React一样,子组件可以跨级获取父组件的状态,后来发现flutter_hook并不是如此,hook和riverpod结合时,hook更像是一个完全的局部管理,并没有Recact Scope这种概念,跨级传递状态。

组合Bloc ?

Bloc是重量级的,声明需要BlocProvider, 消费需要使用BlocConsumer<BlocA, BlocAState>, 这也有点丑陋,虽然我们避免了每一个需要复杂参数都需要声明一个单独的InheritedWidget, 但同样多了很多模版代码。如果是这样的组合,加重了页面的复杂性以及阅读理解难度, 不如直接使用Bloc。

反思, 是不是违背了设计的初衷?

当笔者处处碰壁的时候,想起了之前为了解决打点参数透传而写的一个库data_trakcer, 似乎两者是同样的问题,但不同于打点的简单字段,这里需要明确的状态和通知程序。 回顾响应式的设计原则 数据向下传递,操作向上传递, 似乎认为难点或者痛点其实本不应该被关注, 因为按照设计原则,一切都是合理的,我们必须对每个有操作的组件回调到声明notifer进行调用,或者将参数或notifer进行一级一级的传递。

应该如何是好?

上述思考的过程,让笔者重新梳理了主流的一些状态管理,但还有很多是我不曾使用和了解的,笔者也不确定是否有其他方案解决了我所头疼的问题,也或许根本不是问题。当我在看Bloc Flutter时,笔者发现,Bloc实现局部Scope的原理其实底层是Provider。这个被遗忘的基础状态管理。

static T of<T extends StateStreamableSource<Object?>>(
    BuildContext context, {
    bool listen = false,
  }) {
    try {
      return Provider.of<T>(context, listen: listen);
    } on ProviderNotFoundException catch (e) {
    }
  }

所以,是否可以使用Provider + Rivderpod解决我所遇到的问题?如下代码:

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:https_sync_client/domain/task_provider.dart';
import 'package:provider/provider.dart' as provider;

class TaskDetailScreen extends HookConsumerWidget {
  final int taskId;
  final int planId;
  final int viewId;

  const TaskDetailScreen({
    super.key,
    required this.taskId,
    required this.planId,
    required this.viewId,
  });

  
  Widget build(BuildContext context, WidgetRef ref) {
    final taskDetailNotifier =
        ref.watch(taskDetailProvider(taskId, planId, viewId).notifier);
    return provider.Provider(
      create: (context) => taskDetailNotifier,
      child: const RichEditor(),
    );
  }
}

class RichEditor extends HookConsumerWidget {
  const RichEditor({
    super.key,
  });

  
  Widget build(BuildContext context, WidgetRef ref) {
    return GestureDetector(
      onTap: () {
        context.read<TaskDetail>().update(content: "");
      },
      child: Center(
        child: Container(
          color: Colors.amber,
          width: 100,
          height: 100,
        ),
      ),
    );
  }
}

这段代码似乎成功了,又似乎解决了我的痛点。成本似乎只有provider.Provider一个容器和context.read。能不能真的实现痛点,希望各位自己验证一下,实践才是检验真理的唯一标准, 笔者也不确定这么操作是不是符合最佳实践,但在笔者工作当中两个场景是非常令人头痛的,一个打点,重运营类项目,经常需要按钮级别的打点需求, 第二是,业务复杂的组件且会堆叠的情况。

总结

遇到问题,解决问题是技术人的一个思考准则,当我们遇到丑陋代码时,总可以找到合适的姿势去改变一点,使之优雅好用一点,世界上没有银弹, 但软件开发领域因为不断的进步,也在逐渐的越来越好(至少不想回去做Android原生)。可以把疑问放到评论区,一起讨论。

【Flutter】状态管理:高级状态管理 (Riverpod, BLoC) 当项目变得更加复杂时,简单的状态管理方式(如 `setState()` 或 `Provider`)可能不足以有效地处理应用中状态的变化和业务逻辑的管理。在这种情况下,高级状态管理框架,如 `Riverpod` 和 `BLoC`,可以提供更强大的工具,用于处理复杂的状态流、逻辑分离以及响应式编程。 阅读详情

相关推荐

Flutter Riverpod 最新版介绍及详细使用场景

Riverpod是Flutter生态中强大的状态管理与依赖注入框架,作为Provider的升级版,它不依赖BuildContext,更适合大型项目开发。文章介绍了Riverpod的核心优势:解决状态管理痛点、支持代码分层、统一异步状态处理,并推荐使用NotifierProvider管理交互状态。

爱喝水程序员的博客 523

重走Flutter状态管理之路—Riverpod入门篇

点击上方蓝字关注我,知识会给你力量熟悉我的朋友应该都知道,我好几年前写过一个「Flutter状态管理之路」系列,那个时候介绍的是Provider,这也是官方推荐的状态管理工具,但当时没有写完,因为写着写着,觉得有很多地方不尽人意,用着很别扭,所以在写了7篇文章之后,就暂时搁置了。一晃时间过了这么久,Flutter内部依然没有一个能够碾压一切的状态管理框架,GetX可能是,...

eclipse_xu 3062

hooks_riverpod框架解析

类似 React 的生命周期:挂载时执行回调,卸载时清理。,不同 Provider 适用于不同业务场景。在 Riverpod 里,所有状态都是。

笔沫拾光 1116

Flutter状态管理之Riverpod

Riverpod和Provider师出同门,都来自作者Remi,Riverpod可以被认为是Provider的重写,来实现原本不可能的功能。本篇来介绍一下Riverpod,给大家提供一个新的选择。

唯鹿的博客 1万+

Flutter状态管理利器:Riverpod核心原理与实战

状态管理是现代前端框架的核心概念,通过集中管理应用状态实现数据流的高效控制。Riverpod作为Flutter生态中的新一代状态管理方案,采用编译期安全机制和响应式编程模型,解决了组件间状态共享的耦合问题。其核心价值在于提供类型安全的依赖注入系统,通过Provider模式实现状态的细粒度更新,显著减少不必要的Widget重建。在工程实践中,Riverpod特别适合处理电商购物车、用户认证等需要跨组件状态同步的场景。通过AsyncValue封装可简化异步状态管理,结合select方法实现精确重建优化性能。热词

weixin_34348805的博客 401

Flutter状态管理:Riverpod核心原理与实战应用

状态管理是现代前端框架的核心技术,通过统一的数据流控制实现UI与数据的解耦。Riverpod作为Flutter生态中的新一代解决方案,采用单向数据流架构和智能依赖管理机制,通过Provider、Ref、Consumer三大核心组件构建响应式系统。其技术价值体现在自动依赖追踪、精确重建范围和灵活的状态组合能力上,特别适合电商购物车、实时数据仪表盘等复杂交互场景。在工程实践中,Riverpod的autoDispose修饰符能有效预防内存泄漏,而select方法则可实现像素级重建控制。结合AsyncValue和F

weixin_34378767的博客 471

终极指南:如何优雅处理Riverpod中多个Provider的依赖关系

Riverpod是一个简单而强大的状态管理库,它让开发者能够轻松访问状态,同时保持代码的健壮性和可测试性。本文将详细介绍如何在Riverpod中优雅地处理多个Provider之间的依赖关系,帮助你构建更清晰、更高效的应用架构。 ## 为什么选择Riverpod进行状态管理? 在现代应用开发中,状态管理是一个核心挑战。Riverpod作为Flutter生态系统中的新兴力量,提供了一种声明式的状态

gitblog_00828的博客 368

Riverpod实践:从错误到优雅的代码生成

摘要:本文介绍了解决Flutter中Riverpod注解常见错误"Undefined class 'HelloWorldRef'"的方法。主要原因包括依赖包缺失、代码未生成和缺少part文件声明。解决方案分三步:安装flutter_riverpod、riverpod_annotation等相关依赖包;运行build_runner生成代码;在使用注解的文件中添加part声明。通过正确配置,开发者可以优雅地使用Riverpod进行状态管理,提高开发效率和代码可维护性。

2501_90323865的博客 71

Flutter Assets Audio Player与状态管理:如何优雅集成Provider、Riverpod或Bloc

Flutter Assets Audio Player是一款功能强大的音频播放插件,支持从资产、网络或本地文件播放音乐/音频,兼容Android、iOS、Web和macOS平台,并能显示通知。本文将详细介绍如何将Flutter Assets Audio Player与主流状态管理方案(Provider、Riverpod和Bloc)优雅集成,帮助开发者构建更健壮的音频播放应用。 ## 为什么需要状

gitblog_00187的博客 846

从JTAG到AS模式:一文搞懂EP4CE10E22C8N所有配置引脚(MSEL, nCONFIG, DATA0)的用法

本文深入解析EP4CE10E22C8N FPGA的配置引脚(MSEL, nCONFIG, DATA0)在不同模式下的使用方法,特别关注从JTAG到AS模式的切换要点。通过详细的配置模式对比、状态机分析和PCB布局建议,帮助开发者避免常见陷阱,提升FPGA配置成功率。

weixin_33713350的博客 319

汽车软件工程师必看:ASPICE流程实战指南(附完整产物清单)

本文为汽车软件工程师提供ASPICE流程实战指南,详细解析如何搭建合规开发环境、各阶段文档产出清单及工具链整合策略。通过实战案例和模板资源,帮助团队高效实施ASPICE标准,提升软件开发质量与效率。

weixin_29230805的博客 468

Realm Dart与Flutter状态管理集成:Riverpod、Provider、GetX最佳实践

想要在Flutter应用中实现高效的数据管理和状态同步?Realm Dart作为移动优先的数据库解决方案,与Flutter的流行状态管理库Riverpod、Provider和GetX完美结合,为开发者提供了强大的数据持久化与实时状态管理能力。本文将深入探讨如何将Realm Dart与这些状态管理工具集成,打造响应式、高性能的Flutter应用。 [![Realm Dart与Flutter集成](

gitblog_00987的博客 691

博士申请-考核制经验分享(2)——个人简历

申博过程中一般在联系导师时就将个人简历作为邮件附件,有些学校也会在提交材料或者复试阶段提交个人简历。

weixin_49282401的博客 5520

Flutter 状态管理进阶:从 Provider 到 Riverpod 2.0(原理 + 实战 + 性能优化)

Flutter状态管理方案Riverpod 2.0深度解析:从Provider迁移到性能优化 摘要:本文深入探讨Flutter状态管理方案Riverpod 2.0的核心优势与实战应用。相比传统Provider方案,Riverpod 2.0通过无上下文依赖设计、编译期安全校验和精准重建控制,显著提升了代码可维护性和性能表现。文章详细对比了两种方案的实现差异,展示了计数器、用户状态管理等典型场景的代码示例,并提供了select精准监听、Consumer优化等性能调优技巧。

2501_93660706的博客 1231

海康视觉平台VisionMaster使用学习笔记(1)

双击图像源设置图像源的属性,像素格式分为Mono8和RDB24分别对应导入的图像是彩色还是黑白。打开相机驱动软件MVS,对连接的相机进行属性上的配置,先对相机的IP进行对应的设置。将自动触发的使能打开,保存配置好的相机属性,默认保存到用户集1中。点击MVS软件中的触发按钮,查看相机是否进行正常的触发拍照。打开VM软件添加一个图像源,选择图像源选项拖出图像源。回到VM软件中将选择相机选项选择到配置好参数的相机。取图方式也可以调整为相机取图,将图像源改为相机。双击相机进行连接后对相机的属性进行配置。

A567852的博客 1万+

liquibase扩展支持达梦数据库

近期项目中需要支持国产数据库,需要liquibase底层支持达梦数据库,记录下操作的详细步骤以便分享。 1.liquibase支持的数据库很多如MySQL, PostgreSQL, Oracle, Sql Server, DB2。但是达梦数据库并不支持,所以需要新建DMDatabase类来适配达梦数据库。达梦语法和Oracle很像所以只需要复制liquibase-core下的Oracle Database做些修改就可了。以下为需要修改的地方 public class DMDatabase extends A

qq_43677719的博客 5472

Flutter Riverpod 高级技巧:优雅的状态管理

作为一名把代码当散文写的 UI 匠人,我对 Flutter Riverpod 状态管理有着独特的见解。Riverpod 是 Provider 的进化版,它提供了一种更灵活、更强大的状态管理方式。从简单的状态共享到复杂的异步数据处理,Riverpod 为我们提供了一套全新的状态管理工具。就像指挥家手里的指挥棒一样,Riverpod 让状态管理变得优雅而有序。Flutter Riverpod 是一种优雅、强大的状态管理方案,它可以让我们创建更加可维护、可测试的应用。

Leo 4233

PyTorch实战(30)——使用TorchScript和ONNX导出通用PyTorch模型

在本节中,我们将深入探讨使用 TorchScript 导出 PyTorch 模型。通过序列化,TorchScript 使模型与 Python 生态系统独立,从而使得模型可以在其他环境中加载,例如基于 C++ 的环境。我们还跨越 Torch 框架与 Python 生态的边界,研究机器学习通用开放格式 ONNX,该技术能帮助我们将 PyTorch 训练的模型导出至非 PyTorch 甚至非 Python 环境。

盼小辉丶的博客 3496

Riverpod 状态管理:如何优雅地组合多个异步请求

在现代前端开发中,状态管理是构建复杂应用的关键。Riverpod 作为 Flutter 生态中强大的状态管理工具,提供了灵活的方式来处理异步数据流。本文将深入探讨如何在 Riverpod 中优雅地组合多个相互依赖的异步请求。 ## 为什么需要组合请求 在真实应用场景中,我们经常遇到这样的需求:一个请求的结果需要作为另一个请求的参数。例如: 1. 先获取用户位置,再根据位置获取附近的餐厅 2....

gitblog_00003的博客 557

MetaERP 的管理单元在设计哲学和实现逻辑上,确实与 Oracle EBS 的业务实体(OU)一脉相承,你可以放心地在已知的 Oracle 多组织架构框架下进行理解。它并没有推翻这套经典的核算模型

MetaERP的管理单元设计继承了Oracle EBS业务实体(OU)的核心思想,并进行了现代技术重构。管理单元(MU)作为OU的超集,延续了业务数据隔离与流程执行边界的定位,但通过元数据驱动的多租户架构实现更灵活的数据隔离。MetaERP采用三层解耦设计(核算单元、自然科目、核算维度),解决了EBS科目组合爆炸问题,并实现事件驱动的实时核算。相较于EBS的批处理模式,MetaERP通过云原生架构和元数据驱动配置,显著提升了灵活性、实时性和扩展性,支持跨法人的业务统一管理视图。

金牌架构师 576

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Flutter状态管理利器:全面解析Riverpod六大Provider使用场景

Flutter状态管理利器:全面解析Riverpod六大Provider使用场景 在Flutter应用开发中,状态管理一直是开发者需要面对的重要课题。Riverpod作为新一代状态管理解决方案,提供了六种不同类型的Provider,每种都有其特定的适用场景。本文将深入剖析这些Provider的特点和使用时机,帮助开发者做出更明智的选择。 一、基础概念 Riverpod的Provider体系设计精妙...

gitblog_00536的博客 657

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Riverpod状态管理终极指南:轻松掌握Provider、Ref和AsyncValue的核心用法

Riverpod是一个强大的状态管理库,它提供了一种简单而可靠的方式来访问和管理应用程序状态。无论是小型应用还是大型项目,Riverpod都能帮助你构建可测试、可维护的代码架构。本文将深入解析Riverpod的三大核心概念:Provider、Ref和AsyncValue,带你快速掌握状态管理的精髓。 ## 为什么选择Riverpod进行状态管理? 在Flutter开发中,状态管理一直是开发者面

gitblog_00045的博客 470

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Memo状态管理艺术:Riverpod如何优雅处理复杂学习数据流

在开源间隔重复学习软件Memo中,**Riverpod状态管理**技术被巧妙运用来处理复杂的学习数据流。作为一款面向程序员的**Flutter开源学习工具**,Memo通过优雅的**状态管理架构**实现了高效的数据同步和UI响应,为用户提供了流畅的学习体验。本文将深入解析Memo如何利用Riverpod构建**可维护的应用程序状态**,并展示这种**现代Flutter状态管理**方案在实际项目中的

gitblog_00637的博客 876

Riverpod终极指南:掌握Family、AutoDispose和自定义Provider的10个高级技巧

Riverpod是Flutter生态中最强大的状态管理解决方案,提供了简单易用且高度可测试的状态访问方式。无论你是初学者还是经验丰富的开发者,掌握Riverpod的高级用法都能显著提升你的应用开发效率。 ## 理解Riverpod的核心概念 在深入高级用法之前,让我们快速了解Riverpod的基本架构。Riverpod通过ProviderScope作为全局状态容器,管理着整个应用的状态树。每个

gitblog_01017的博客 376

Flutter Riverpod:状态管理的新纪元

告别 Provider 的繁琐,拥抱 Riverpod 的简洁与强大。

Leo 1027
上一篇: Flutter中被屏蔽的概念,Scheduler(调度器)
PirateBrook
博客等级 码龄11年 90粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值