首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在StreamBuilder内部构建期间调用setState()或markNeedsBuild()

在StreamBuilder内部构建期间调用setState()或markNeedsBuild()是一种常见的错误做法。StreamBuilder是Flutter框架中的一个小部件,用于根据来自流的异步事件来构建小部件树。在StreamBuilder内部构建期间调用setState()或markNeedsBuild()可能会导致无限循环的重建,从而导致性能问题和不稳定的UI。

StreamBuilder的工作原理是,它监听一个流并在每次接收到新的事件时重新构建小部件树。在构建期间调用setState()或markNeedsBuild()会触发重建,而重建又会导致新的事件被接收到,从而再次触发重建,形成无限循环。

为了避免这个问题,我们应该避免在StreamBuilder内部构建期间调用setState()或markNeedsBuild()。相反,我们应该在StreamBuilder外部的其他地方调用这些方法来更新UI。例如,可以在StreamBuilder外部的按钮点击事件中调用setState()来更新UI。

如果需要在StreamBuilder内部进行状态管理,可以考虑使用其他状态管理方案,如Provider、GetX或Bloc。这些状态管理方案可以更好地处理异步事件,并提供更好的性能和可维护性。

总结起来,避免在StreamBuilder内部构建期间调用setState()或markNeedsBuild(),可以提高应用的性能和稳定性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Flutter完整开发实战详解(十一、全面深入理解Stream)

i 广播和非广播的区别在于调用 _createSubscription 时,内部对接口类 _StreamControllerLifecycle 的实现,同时它们的差异在于: _StreamController...二、StreamBuilder 如下代码所示, Flutter 中通过 StreamBuilder 构建 Widget ,只需提供一个 Stream 实例即可,其中 AsyncSnapshot 对象为数据快照...image 如上图所示, StreamBuilder调用逻辑主要在 _StreamBuilderBaseState 中,_StreamBuilderBaseState initState 、didUpdateWidget...中会调用 _subscribe 方法,从而调用 Stream 的 listen,然后通过 setState 更新UI,就是这么简单有木有?...我们常用的 setState 中其实是调用markNeedsBuildmarkNeedsBuild 内部标记 element 为 diry ,然后在下一帧 WidgetsBinding.drawFrame

3.5K41

Flutter 绘制探索 4 | 深入分析 setState 重建和更新 | 七日打卡

这个系列便是对 Flutter 绘制的探索,通过测试、调试及源码分析来给出一些绘制时被忽略从未知晓的东西,而有些要点如果被忽略,就很可能出现问题。...第一篇也说过,对于有 滑动 动画 需求的绘制,重建触发的频率非常大,此时即使对象是 轻量的,也会在短时间内创建大量对象,这样不是很好。...现在也就是即将调用这个 Element 对象的 markNeedsBuild() 方法。 ? ---- 下一步就会进入 Element.markNeedsBuild,也就是 Element 类中。...这就是 setState 时进行的 Element 重新构建 和 RenderObject 的更新。...---- StreamBuilder 组件根据 Stream 的状态,使用 setState 进行重新构建的。 ?

1.8K20

Flutter完整开发实战详解(十五、全面理解State与Provider)

问题就在于前面 StatefulElement 的构建方法和 update 方法: State 只 StatefulElement 的构建方法中创建,当我们调用 setState 触发 update...我们常说的 setState ,其实是调用markNeedsBuildmarkNeedsBuild 内部会标记 element 为 diry,然后在下一帧 WidgetsBinding.drawFrame...状态共享是常见的需求,比如用户信息和登陆状态等等,而 Flutter 中 InheritedWidget 就是为此而设计的,第十二篇我们大致讲过它: Element 的内部有一个 Map<Type...接着我们逐个分析 1、Delegate 既然是状态管理,那么肯定有 StatefulWidget 和 setState 调用。...listener 内会调用 StateDelegate 的 StateSetter 方法,从而调用到 StatefulWidget 的 setState

3.5K21

告别setState()! 优雅的UI与Model绑定 Flutter DataBus使用~

但随着当app的交互变得复杂,setState出现的次数便会显著增加,每次setState都会重新调用build方法,这势必对于性能以及代码的可阅读性带来一定的影响。...当我们点击按钮时使本地变量key1,key2做增加操作,之后调用setState()。 ? img ? img ? img ?...这样Widget的构建完全由Stream触发,控件无需自行setState,它的构建完全由数据驱动,是一种响应式编程。也是许多开源框架例如Bloc等核心原理。...key1的点击事件中往Stream中add数据,这样key1的流上产生了一条数据,对应的监听者收到数据后,只更新自己的内容,不会重建其他区域。 ? ? ?...例如直接在Widget中混入改类,调用getLine方法获取到StreamBuilder

2.4K41

flutter源码:setState分析

setState方法算是flutter使用最频繁的方法了,每次页面数据有改变,都需要调用这个方法,去触发页面的刷新,展示最新的UI效果,接下来从源码角度解读下setState后具体发生了什么 系统源码部分...markNeedsBuild(); } 上面可以看到,回调方法VoidCallback fn是马上会被同步执行,然后调用这个widget对应的element的markNeedsBuild方法 void...markNeedsBuild() { if (dirty) return; _dirty = true; owner!....scheduleBuildFor(this); } 就是把这个element标记为dirty,如果已经标记过,则忽略,说明连续调用两次setState方法,第二次其实是多余的,然后是调用owner...ensureFrameCallbacksRegistered(); window.scheduleFrame(); } 这个方法,其实就是让系统触发下一帧的刷新,系统刷新有固定的频率,一般是一秒60帧,内部已经是底层的方法了

55810

Flutter的setState更新原理和流程

也就是只有当我们的类是有状态类的时候才能进行状态刷新,setState也是State(有状态类)类里 解析 :framework.dart文件State类 调用 setState() 必须是没有调用过..._element.markNeedsBuild(); } setState方法除了一些条件判断就是:_element.markNeedsBuild();那我们看看markNeedsBuild。... drawFrame 中调用 buildOwner.buildScope(renderViewElement)更新 elements。..._active=false 的时候直接返回 管理类 1.告诉管理类方法自己需要被重新构建: owner.scheduleBuildFor(this) 调用 window.scheduleFrame()...等待下一次vsync信号的到来, 然后再经过层层调用最终会调用到 Window::BeginFrame() UI 的绘制逻辑是 Render 树中实现的 更新帧信号来临从而刷新需要重构的界面 drawFrame

73820

【 Flutter 极限测试】连续 1000000 次 setState 会怎么样

测试描述 可能很多人会认为,每次的 State#setState 都会触发当前状态类的 build 方法重新构建。但真的是这样吗,你真的了解 Flutter 界面的更新流程吗?...源码调试分析 如下, State#setState 源码中可以看出,它只做了两件事: 触发入参回调 fn 。 执行持有元素的 markNeedsBuild 方法。... Elememt#markNeedsBuild 方法中没有一个非常重要的判断,那就是下面 4440 行 中,如果 dirty 已经是 true 时,则直接返回,不会执行接下来的方法。...总的来说, State#setState 的核心作用就是把持有的元素标脏并申请新帧调度。而只有新帧到来,执行完构建之后,元素的 dirty 才会置为 false 。...也就是说,两帧之间,无论调用多少次 setState ,都只会触发一次, 元素标脏 和 申请新帧调度 。这就是为什么连续触发 1000000 次,并无大事发生的原因。

61230

StatefulWidget的使用案例

首先我们VSCode中安装一个名为“Awesome Flutter Snippets”的插件,该插件提供了Flutter中各种常用的类和方法的快速构建方式,可以极大地提升开发效率,如下所示: 捷径...dis 部署 永久地从树中删除此对象时调用。当此State对象永远不会再次构建时,框架将调用此方法。...reassemble 重新安装 调试期间重新组装应用程序时调用,例如在热重新加载期间。...streamBldr Stream Builder StreamBuilder根据与指定交互的最新快照创建新的构建自身stream animatedBldr 动画生成器 创建动画生成器...这是基于与Future交互的最新快照构建的。 nosm 没有这样的方法 访问不存在的方法属性时,将调用此方法。

3.3K20

Flutter | 一文搞懂 BuildContext

其实在 SetState 中,最终也是调用markNeedsBuild 方法,如下: void setState(VoidCallback fn) { assert(fn !...markNeedsBuild(); } 复制代码 我们写代码的过程中还会发现一个问题,就是要更新的状态不是必须要写在 setState 里面,只要写在 setState 上面 即可,这样也没有问题,...但是最后发现了这个问题的弊端了,如大多数人会在每个方法的后面加一个 setState,导致过度的开销,并且删除的时候也是不知道这个这个 setState 到底有没有实际的意义,这就会造成一些不必要的麻烦...所以 Flutter setState 中加了一个回调,我们可以需要更新的状态直接放在回调里面,和状态没关系的放在外边即可。...findAncestorStateOfType 方法来获取的 Scaffold 的状态,最终来实现一些操作, Theme.of(context).accentColor 我们可以通过如上的方法来获取一下主题颜色等,其内部实现如下

52530

Widget的生命周期和渲染原理

我们知道,需要修改数据更新UI的时候,只要调用setState然后在其中更改数据,这样UI就可以随之改变了,这是因为setState函数可以触发widget的销毁重建,也就是会触发state的build...接下来我们看一下setState的源码: 可以看到,除了断言,这里面实际上就调用了一行代码: _element!....好,现在我们知道了通过setState来根据数据自动调整UI的原理了,因此,原则上我们是可以不调用setState而直接给element调用markNeedsBuild函数来实现UI的更新,即: StatefulWidget...Widget的渲染原理 关于Widget的渲染,我Widget,构建Flutter界面的基石中有过介绍,本文也是依次为基准,再做一些拓展介绍。...StatefulElement; StatefulElement的构建函数中,调用了widget的createState函数来创建State,并且给创建出来的State对象的element和wiget

1.2K20

Flutter | 启动,渲染,setState 流程

组件树构建完毕后,回到 runApp 的实现中,当调完 attachRootWidget 后,最后一行会调用 WidgetsFlutterBainding 实例的 scheduleWarmUpFrame...markNeedsBuild(); } 复制代码 void markNeedsBuild() { ....// //标注该 element 需要重建 _dirty = true; owner..._inDirtyList = true; } 复制代码 当调用 setState 后: 1,首先调用 markNeedsBuild 方法,将 element 的 dirty 标记为 true,表示需要重建...到此,setState 中最核心的就是触发了一个 请求,在下一次屏幕刷新的时候就会回调 onBeginFrame,执行完成之后才会调用 onDrawFrame 方法。...上屏,会将绘制出的bit数据发送给GPU .....///// } } 复制代码 以上,便是 setState 调用的大概过程,实际的流程会更加复杂一点,例如在这个过程中不允许再次调用 setState

1.1K10

Flutter框架分析(三)-- Widget,Element和RenderObject

如果当前State不是mounted == true的状态,你去调用setState()是会crash的。 函数initState()用来初始化State。...函数setState()我们很熟悉了。这个函数只是简单执行传入的回调然后调用_element.markNeedsBuild()。你看,如果此时_element为空的时候会不会出问题?...所以建议大家调用setState()之前用mounted判断一下。另外要注意的一点是,这个函数也是触发渲染流水线的一个点。...函数rebuild()渲染流水线的构建(build)阶段被调用。具体的重建在函数performRebuild()中,由Element子类实现。...其内部实现主要是维护对其有依赖的子Element的Map,以及需要的时候调用子Element对应的didChangeDependencies()回调,这里就不贴代码了,大家感兴趣的话可以自己去看一下源码

1.2K10

Flutter | 事件循环,Future

正文 Dart 中,没有多线程的概念,所谓的异步操作全部都是一个线程里面执行的, 并且不会造成卡顿的原因就是事件循环(Event Loop), 如下图所示,程序的运行过程中,会有两个事件..., scheduleMicrotask(() { print("Hello Flutter"); }); 复制代码 Future.microtask() //内部调用的也是上面的函数 复制代码 但是需要注意的是...Future.whenComplete() 类似于 try catch 后面的 finnaly,无论成功和失败,最终都会执行到这里 Future.them 链式调用 // them 中可以接继续返回值...,该值会在下一个链式的 then 调用中拿到返回的结果 getNetData().then((value) { //支持成功到此处 print(value); return "data1";...做的小游戏 日常开发中,StreamBuilder 还是挺实用的,这次我们用 StreamBuilder 来做一个小游戏,先看效果: 从上面的动画来看,可以将其分为三个部分,第一个部分则是底部的键盘

4.2K10
领券