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

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

在构建期间调用 setState()markNeedsBuild() 是 Flutter 框架中常见的操作,但也是容易引发问题的行为。下面我将详细解释这些概念及其相关问题,并提供解决方案。

基础概念

  1. setState():
    • setState() 是 Flutter 中用于通知框架某个状态已经改变,需要重新调用 build 方法来更新 UI。
    • 通常在用户交互或数据更新时调用。
  • markNeedsBuild():
    • markNeedsBuild() 是 Flutter 中的一个低级方法,用于标记当前 widget 需要重新构建。
    • 它不会立即触发 build 方法,而是将重建任务添加到事件队列中,等待 Flutter 的事件循环处理。

相关问题

在构建期间调用 setState()markNeedsBuild() 会导致以下问题:

  1. 无限重建:
    • 如果在 build 方法中调用 setState(),会导致 build 方法再次被调用,从而形成无限循环。
  • 性能问题:
    • 频繁调用 setState()markNeedsBuild() 会导致 UI 不断重建,影响应用性能。

原因分析

  • 无限重建:
    • build 方法中调用 setState() 会导致 build 方法再次被调用,因为 setState() 会标记 widget 需要重建。
    • 这种递归调用会一直持续下去,直到应用崩溃。
  • 性能问题:
    • 每次调用 setState()markNeedsBuild() 都会触发 UI 重建,如果频繁调用,会导致 CPU 和 GPU 负载过重,影响应用性能。

解决方案

  1. 避免在 build 方法中调用 setState():
    • 确保 setState() 只在用户交互或数据更新时调用,而不是在 build 方法中。
  • 使用 Future.microtask:
    • 如果需要在构建期间进行某些操作并更新状态,可以使用 Future.microtask 来延迟执行 setState()
    • 如果需要在构建期间进行某些操作并更新状态,可以使用 Future.microtask 来延迟执行 setState()
  • 使用 initStatedispose:
    • 对于需要在 widget 生命周期内进行的初始化和清理操作,可以使用 initStatedispose 方法。
    • 对于需要在 widget 生命周期内进行的初始化和清理操作,可以使用 initStatedispose 方法。

应用场景

  • 用户交互:
    • 当用户点击按钮或滑动屏幕时,调用 setState() 更新 UI。
  • 数据更新:
    • 当从网络或本地数据库获取新数据时,调用 setState() 更新 UI。

参考链接

通过以上解释和建议,希望你能更好地理解 setState()markNeedsBuild() 的使用场景及其相关问题,并能有效地解决这些问题。

相关搜索:在StreamBuilder内部构建期间调用setState()或markNeedsBuild()TextFormField:构建期间调用的setState()或markNeedsBuild()Flutter -构建期间调用的setState()或markNeedsBuild()收到错误“在构建期间调用了setState()或markNeedsBuild()”Flutter:在使用Provider构建期间调用的setState()或markNeedsBuild()在使用提供程序生成期间调用setState()或markNeedsBuild()在构建过程中调用setState()或markNeedsBuild()错误:在生成期间调用了setState()或markNeedsBuild()Flutter Hooks使用构建期间调用的useEffect - setState()或markNeedsBuild()获取数据Flutter Provider - setstate或markneedsbuild()在构建过程中调用在构建期间调用setState()或markNeedsBuild()。将GestureDetector放入容器中重构AKA后出错在构建期间调用setState()或markNeedsBuild(),在Flutter中使用FutureBuilder中的Provider和StreamBuilder在构建期间调用setState()或markNeedsBuild()。导致小部件的相关错误是RoundIconButton。A RenderFlex溢出Flutter Provider带有listen false,但仍然得到错误"setState()或markNeedsBuild()在构建期间被调用“。在小部件构建期间调用setState()在构建期间调用setState()或markNeedsBuild()。尝试在flutter中创建一个简单的计时器获取异常:setState()或markNeedsBuild()未处理的异常:在生成期间调用了setState()或markNeedsBuild()。BlocListener内幕显示和隐藏小部件生成错误期间调用的SetState()或markNeedsBuild()颤动显示对话框在构建过程中调用的setState()或markNeedsBuild()
相关搜索:
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

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

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

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

    67130

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

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

    1.9K20

    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...的scheduleBuildFor方法 这里的owner,是BuildOwner,先记住全局只有一个BuildOwner实例,它是启动的时候创建的,这里先不展开说明,我们先记住全局就一个owner就好

    58810

    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.3K20

    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.2K10

    Flutter | 一文搞懂 BuildContext

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

    54430

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

    Element不会去管具体的颜色,字体大小,显示内容等等这些UI的配置描述,也不会去管布局,绘制这些事,它只管自己的那棵树。Element的主要工作都处于渲染流水线的构建(build)阶段。...如果当前State不是mounted == true的状态,你去调用setState()是会crash的。 函数initState()用来初始化State。...函数setState()我们很熟悉了。这个函数只是简单执行传入的回调然后调用_element.markNeedsBuild()。你看,如果此时_element为空的时候会不会出问题?...所以建议大家调用setState()之前用mounted判断一下。另外要注意的一点是,这个函数也是触发渲染流水线的一个点。...函数rebuild()渲染流水线的构建(build)阶段被调用。具体的重建在函数performRebuild()中,由Element子类实现。

    1.3K10

    Flutter进阶-Key之GlobalKey

    我们这不做深入讨论,只需要知道element树构建中是会将owner传递,即共享一个owner对象。...实现原理: 开始探索原理之前,我们需要明白setState的流程,我们简单过一下,setState之后,会将当前widget(MyHomePage)markNeedsBuildmarkNeedsBuild...递归child更新,RenderObjectElement则是更新RenderObject,如果是带childchildren的RenderObjectElement最终也会调用到updateChild...答案是有的,inflateWidget递归构建新的element树时,会判断widget key是否是GlobalKey,是的话尝试调用_retakeInactiveElement,_retakeInactiveElement...答案是会的,但是build方法调用不代表我们的widget被重新绘制,Flutter中build方法是生成widget配置信息的,是很轻量也是会被频繁调用

    1.8K20

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

    如下图所示,StatefulWidget 的 createState 是 StatefulElement 的构建方法里创建的, 这就保证了只要 Element 不被重新创建,State 就一直被复用...问题就在于前面 StatefulElement 的构建方法和 update 方法: State 只 StatefulElement 的构建方法中创建,当我们调用 setState 触发 update...我们常说的 setState ,其实是调用markNeedsBuildmarkNeedsBuild 内部会标记 element 为 diry,然后在下一帧 WidgetsBinding.drawFrame...接着我们逐个分析 1、Delegate 既然是状态管理,那么肯定有 StatefulWidget 和 setState 调用。...listener 内会调用 StateDelegate 的 StateSetter 方法,从而调用到 StatefulWidget 的 setState

    3.6K21

    Flutter学习之构建、布局及绘制三部曲

    构建 初次构建 flutter的入口main方法直接调用了runApp(Widget app)方法,app参数就是我们的根视图的Widget,我们直接跟进runApp方法 void runApp(...时 //2.当Element第一次构建由mount方法去调用 //3.当Widget改变时,被update方法调用 void rebuild() { if (!...,Element(第一层Element)的mount方法主要是确定当前Element整个树种的位置并插入;ComponentElement(第二层)的mount方法先构建Widget树,让后再递归更新...通过setState触发构建 通常我们应用中要更新状态都是通过State中的setState方法来触发界面重绘,setState方法就是先调用了callback让后调用该State的Element对象的...markNeedsBuild方法,markNeedsBuild中将Element标记为dirty并通过BuildOwner将其添加到dirty列表中并调用onBuildScheduled回调(WidgetsBinding

    99410

    【源码篇】Flutter Provider的另一面(万字图文+插件)

    关于Provider的源码,如果对设计模式面向接口编程不熟悉的话,看起来是相当懵逼的,基本就是:懵逼树上懵逼果,懵逼树下你和我;Provider源码使用了大量的抽象类,调用父类构造函数,继承实现断言,...的text值,然后TextField数据框里的数据也及时改变了,其实最后还是用到setState。..., ); } } _InheritedProviderScope 这里是继承了InheritedWidget,里面重写createElement方法,构建Widget的时候,这个方法是肯定会被调用的...这里直接给出结论了,还是 _InheritedProviderScopeElement这个上下文类里面 reassemble:全局状态的初始化逻辑热重载的时候被调用 _delegateState首先在...markNeedsBuild() 可以理解为:最终会调用该Widget的build方法 markNeedsBuild()就不讲了,内部涉及逻辑太多了,还涉及bind类,还会涉及到绘制流程,我嘞个去。。。

    1.4K61
    领券