Flutter 核心技术与实战
陈航
前美团点评高级技术专家
42432 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 48 讲
Flutter 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

30 | 为什么需要做状态管理,怎么做?

实现状态管理的便利性
Provider的优势
多个数据状态的共享
控制UI刷新粒度
数据的读写操作
数据资源的注入
数据状态的封装
简单易用
解决数据共享问题
依赖注入
Provider
fish_redux
flutter_mobx
flutter_redux
思考题
总结
多状态的资源封装
Consumer的作用
Provider的使用
Provider的特点
Flutter状态管理框架的设计思想
状态管理框架的必要性
组件间数据共享的关键
跨渲染引擎页面切换的关键
封装、注入、读写:Flutter的状态管理应该怎么做?

该思维导图由 AI 生成,仅供参考

你好,我是陈航。
在上一篇文章中,我与你分享了如何在原生混编 Flutter 工程中管理混合导航栈,应对跨渲染引擎的页面跳转,即解决原生页面如何切换到 Flutter 页面,以及 Flutter 页面如何切换到原生页面的问题。
如果说跨渲染引擎页面切换的关键在于,如何确保页面跳转的渲染体验一致性,那么跨组件(页面)之间保持数据共享的关键就在于,如何清晰地维护组件共用的数据状态了。在第 20 篇文章“关于跨组件传递数据,你只需要记住这三招”中,我已经与你介绍了 InheritedWidget、Notification 和 EventBus 这 3 种数据传递机制,通过它们可以实现组件间的单向数据传递。
如果我们的应用足够简单,数据流动的方向和顺序是清晰的,我们只需要将数据映射成视图就可以了。作为声明式的框架,Flutter 可以自动处理数据到渲染的全过程,通常并不需要状态管理。
但,随着产品需求迭代节奏加快,项目逐渐变得庞大时,我们往往就需要管理不同组件、不同页面之间共享的数据关系。当需要共享的数据关系达到几十上百个的时候,我们就很难保持清晰的数据流动方向和顺序了,导致应用内各种数据传递嵌套和回调满天飞。在这个时候,我们迫切需要一个解决方案,来帮助我们理清楚这些共享数据的关系,于是状态管理框架便应运而生。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Flutter状态管理一直备受关注,而本文介绍了Flutter中的状态管理框架Provider。该框架简单易用,借鉴了React的设计思想,通过依赖注入的方式实现更加灵活的数据处理和传递。文章通过示例演示了如何使用Provider共享数据状态,并展示了在两个页面中如何读写共享的状态。通过对Provider的使用示例,读者可以了解如何封装数据状态、将数据资源注入到应用中,并在子Widget中进行数据的读写操作。此外,文章还介绍了Consumer的使用,它可以精确地控制UI刷新粒度,避免与数据无关的组件的无谓刷新。通过Provider来实现数据传递,无论在单个页面内还是在整个App之间,都可以方便地实现状态管理,开发出简单、层次清晰、可扩展性高的应用。文章最后留下了思考题,引发读者思考和讨论。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Flutter 核心技术与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(21)

  • 最新
  • 精选
  • Carlo
    老师,我们在生产环境的项目比较大,我们通过建造一个DependencyProvider class DependencyProvider { DependencyProvider._(); static DependencyProvider _sharedInstance; static DependencyProvider get sharedInstance { return _sharedInstance; } UserService get userService => UserService.sharedInstance(persistenceService); } 然后通过在页面中注入页面所需的Service来共享数据 DependencyProvider.sharedInstance.userService 感觉也比较清晰,不知道您怎么评价这种机制? 跟Provider相比的优劣势是什么呢? 谢谢您的回复!

    作者回复: 以单例模式共享数据,本质上和全局变量共享数据类似,全局可见,读写效率高,适合代码量少、功能也少、相对比较简单的程序。 对于代码量大、功能又多、逻辑又复杂的工程来说,就不建议用单例/全局变量了。主要有以下几个原因: 1.代码对单例产生耦合依赖,破坏了代码的封装性/独立性 2.变量的读写处于无序状态,每个模块都可以去读写数据,对系统维护及调试非常不利 3.变量常驻内存,无法释放

    2019-11-25
    8
  • 小石头若海
    老师说的“事实上,当我们使用Provider后,我们就再也不需要使StatefulWidget了”这句不太合理吧。。。😂 这是不是会导致Provider的滥用,还是应该把一些共享的数据放在Provider中,其他的交给组件自治更好

    作者回复: 哈,这是个夸张的语法,形容provider的强大:)实际上StatefulWidget的用途不仅是通过数据变更驱动UI更新,还涉及到状态流转的各个生命周期,这些provider是搞不定的。技术领域没有银弹,还是得看具体场景

    2019-09-05
    6
  • 时光念你
    InheritWidget.of只会找到当前widget树中距离当前节点最近的type对象。同样类型的共享对象,要么另一个对象变成共享对象的子类类型,要么改成持有关系。

    作者回复: 赞

    2019-12-24
    4
    3
  • 🌝
    老师, ChangeNotifier中有dispose方法, 这个方法又应该在是情况下才使用的到?

    作者回复: 需要释放封装对象资源的时候,比如在用文件做持久化的场景。

    2019-10-16
    3
    3
  • 辉哥
    老师,实现两个类型相同对象共享,是不是依靠共享对象的两个相同类型的成员实现到

    作者回复: 可以,赞👍

    2019-09-30
    2
    2
  • 满大大
    我理解应该是需要夸页面共享才用provider吧,它应该是一个单利吧,正常情况下还是少用,对不对

    作者回复: 涉及到复杂的状态共享情况,无论是单页面还是跨页面,都推荐使用Provider

    2019-09-26
    1
  • ray
    一直觉得Provider的Consumer~Consumer6不够优雅

    作者回复: 确实不优雅

    2019-09-05
    2
    1
  • Carlo
    能不能再解释下Provider.of ?获取对象不是按照数据类型来定的吧?比如如果我还有个lineHeight,那写成 final _counter = Provider.of<CounterModel>(context);//获取计时器实例 final textSize = Provider.of<double>(context);//获取字体大小 final lineHeight = Provider.of<double>(context); 照数据类型一样的情况下,如何知道我获取的是textSize还是lineHeight?

    作者回复: 包一个大对象就可以了

    2019-11-25
    2
  • 🌝
    老师,Provider的数据会在跳转页面的时候清除掉。我该如何去处理这个问题?

    作者回复: 你检查下组件的生命周期看看是不是有销毁/新建

    2019-11-08
    3
  • 离尘不离人คิดถึง
    final _counter = Provider.of<CounterModel>(context); return Scaffold( appBar: AppBar( title: Text('DataFlow Page2'), ), //展示资源中的数据 body: Consumer<CounterModel>( builder: (context, CounterModel counter, _) => Center( child: Text('Value: ${counter.counter}') ) ), // floatingActionButton: FloatingActionButton( // child: TestIcon(), // onPressed: _counter.increment, // ), //用资源更新方法来设置按钮点击回调 floatingActionButton: Consumer<CounterModel>( builder: (context, CounterModel counter, child) => FloatingActionButton( onPressed: _counter.increment, child: child, ), child: TestIcon(), ) ); 如上代码所示,在测试的时候发现,按钮还是会不断的刷新重建

    作者回复: 你的第一行代码有主动获取build上下文:final _counter = Provider.of<CounterModel>(context);

    2019-10-28
    3
收起评论
显示
设置
留言
21
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部