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

收到错误“在构建期间调用了setState()或markNeedsBuild()”

这个错误信息表明在Flutter框架的构建(build)过程中,尝试调用了setState()markNeedsBuild()方法。这是不被允许的,因为构建过程应该是纯函数式的,不应该包含任何状态变更操作。

基础概念

  • setState(): 这是Flutter中的一个方法,用于通知框架状态已经改变,需要重新构建Widget树的一部分。
  • markNeedsBuild(): 这是一个低级方法,用于标记一个Widget需要重新构建。

错误原因

在Flutter中,构建过程应该是确定性的,不应该有任何副作用,比如修改状态。如果在构建过程中调用了setState()markNeedsBuild(),就会导致这个错误。

解决方法

  1. 避免在构建方法中调用setState(): 确保不在build()方法或其调用的任何函数中调用setState()
  2. 使用FutureBuilder或StreamBuilder: 如果你需要根据异步数据来构建UI,应该使用FutureBuilderStreamBuilder,而不是在构建过程中等待异步操作完成并调用setState()
  3. 使用initState()初始化状态: 如果需要在Widget初始化时设置状态,应该在initState()方法中进行,而不是在build()中。
  4. 使用didChangeDependencies(): 如果状态更新依赖于某些依赖项的变化,可以使用didChangeDependencies()方法来处理这些情况。

示例代码

假设我们有一个简单的计数器应用,错误地尝试在build()方法中增加计数器的值:

代码语言:txt
复制
class MyCounter extends StatefulWidget {
  @override
  _MyCounterState createState() => _MyCounterState();
}

class _MyCounterState extends State<MyCounter> {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    // 错误的做法:在build方法中调用setState
    // setState(() { count++; });

    return Scaffold(
      appBar: AppBar(title: Text('Counter')),
      body: Center(
        child: Text('Count: $count'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() { count++; });
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

正确的做法是将状态更新逻辑放在FloatingActionButtononPressed回调中,而不是在build()方法中。

应用场景

  • 当你需要根据用户交互或其他事件来更新UI时,应该在事件处理函数中调用setState()
  • 当你需要根据异步数据来构建UI时,应该使用FutureBuilderStreamBuilder

通过遵循这些最佳实践,可以避免在构建过程中调用setState()markNeedsBuild(),从而解决这个错误。

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

相关·内容

  • Flutter | 启动,渲染,setState 流程

    onDrawFrame => _onDrawFrame; // 点击或指针事件回调 PointerDataPacketCallback get onPointerDataPacket => _...组件树在构建完毕后,回到 runApp 的实现中,当调完 attachRootWidget 后,最后一行会调用 WidgetsFlutterBainding 实例的 scheduleWarmUpFrame..., /// 执行一些持久的任务(每一个 frame 都要执行的任务),比如渲染官线(构建,布局,绘制) /// 就是在该任务队列执行的 persistentCallbacks, //..._inDirtyList = true; } 复制代码 当调用 setState 后: 1,首先调用 markNeedsBuild 方法,将 element 的 dirty 标记为 true,表示需要重建...到此,setState 中最核心的就是触发了一个 请求,在下一次屏幕刷新的时候就会回调 onBeginFrame,执行完成之后才会调用 onDrawFrame 方法。

    1.2K10

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

    这个系列便是对 Flutter 绘制的探索,通过测试、调试及源码分析来给出一些在绘制时被忽略或从未知晓的东西,而有些要点如果被忽略,就很可能出现问题。...在第一篇也说过,对于有 滑动 或 动画 需求的绘制,重建触发的频率非常大,此时即使对象是 轻量的,也会在短时间内创建大量对象,这样不是很好。...经过断言后,会执行回调方法,并执行 _element.markNeedsBuild() 。可以看到 setState 方法主要就是执行这个方法,那 _enement 是什么呢? ?...这里只是调用了一下 ensureVisualUpdate。 ?...这就是在 setState 时进行的 Element 重新构建 和 RenderObject 的更新。

    2K20

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

    测试描述 可能很多人会认为,每次的 State#setState 都会触发当前状态类的 build 方法重新构建。但真的是这样吗,你真的了解 Flutter 界面的更新流程吗?...】 1、测试代码说明 如下所示,在默认案例基础上添加了两个蓝色文字,点击时分别触发如下的 _increment1 和 _setState1000000 。...源码调试分析 如下,在 State#setState 源码中可以看出,它只做了两件事: 触发入参回调 fn 。 执行持有元素的 markNeedsBuild 方法。...在 Elememt#markNeedsBuild 方法中没有一个非常重要的判断,那就是下面 4440 行 中,如果 dirty 已经是 true 时,则直接返回,不会执行接下来的方法。...总的来说, State#setState 的核心作用就是把持有的元素标脏并申请新帧调度。而只有新帧到来,执行完构建之后,元素的 dirty 才会置为 false 。

    69130

    Flutter | 一文搞懂 BuildContext

    其实在 SetState 中,最终也是调用的 markNeedsBuild 方法,如下: void setState(VoidCallback fn) { assert(fn !...markNeedsBuild(); } 复制代码 我们在写代码的过程中还会发现一个问题,就是要更新的状态不是必须要写在 setState 里面,只要写在 setState 上面 即可,这样也没有问题,...但是最后发现了这个问题的弊端了,如大多数人会在每个方法的后面加一个 setState,导致过度的开销,并且在删除的时候也是不知道这个这个 setState 到底有没有实际的意义,这就会造成一些不必要的麻烦...所以 Flutter 在 setState 中加了一个回调,我们可以需要更新的状态直接放在回调里面,和状态没关系的放在外边即可。...参考文献 B站王叔不秃 如果本文有帮助到你的地方,不胜荣幸,如有文章中有错误和疑问,欢迎大家提出!

    56130

    Widget的生命周期和渲染原理

    其实,所谓的生命周期,就是一系列的方法回调,我们可以通过实现这些方法来捕获一个widget从加载到卸载全过程中的各个节点,以在合适的时机做合适的事情。 那么我们可以利用生命周期方法做哪些事情呢?...接下来我们看一下setState的源码: 可以看到,除了断言,这里面实际上就调用了一行代码: _element!....好,现在我们知道了通过setState来根据数据自动调整UI的原理了,因此,原则上我们是可以不调用setState而直接给element调用markNeedsBuild函数来实现UI的更新,即: 在StatefulWidget...Widget的渲染原理 关于Widget的渲染,我在Widget,构建Flutter界面的基石中有过介绍,本文也是依次为基准,再做一些拓展介绍。...StatefulElement; 在StatefulElement的构建函数中,调用了widget的createState函数来创建State,并且给创建出来的State对象的element和wiget

    1.3K20

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

    的text值,然后在TextField数据框里的数据也及时改变了,其实最后还是用到setState。...这地方调用了_CreateInheritedProvider类的createState() 方法,安心了 performRebuild:该回调会在setState或者build的时候会触发;此处做了一个判断...底下也调用了 startListening,说明从外面传进来的这个回调也调用了,将 上下文实例 和 传进来的XxxProvider实例 作为入参传进了这个回调中,此处传进来的回调也通过 .call 被调用了...performRebuild回调中会赋初值 在reassemble回调中,_delegateState调用了value( _delegateState.value ) 所以 get value 肯定会在初始化的时候被调用...markNeedsNotifyDependents 当我们使用 notifyListeners(),就会触发,这个回调 此处调用了 markNeedsBuild(),然后给 _shouldNotifyDependents

    1.5K61

    Flutter 的 runApp 与三棵树诞生流程源码分析

    或者说,在你入门 Flutter 后应该经常听到或看到过 Flutter 三棵树核心机制的东西,你有真正的想过他们都是什么吗?如果都没有,那么本文就是一场解密之旅。...的属性,以便 window 收到屏幕事件后调用,window 实例是 Framework 层与 Engine 层处理屏幕事件的桥梁。...*/ _buildOwner = BuildOwner(); //2、回调方法赋值,当第一个可构建元素被标记为脏时调用。 buildOwner!....//进而本质调用了window.scheduleFrame()方法。 SchedulerBinding.instance!....因为前面window.scheduleFrame()发起的绘制请求是在收到系统 VSYNC 信号后才真正执行,而 Flutter app 初始化时为了尽快呈现 UI 而没有等待系统 VSYNC 信号到来就主动发起一针绘制

    92800

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

    总的来说就是以下几点: Widget是对Element的配置或描述。Flutter app开发者主要的工作都是在和Widget打交道。...Element不会去管具体的颜色,字体大小,显示内容等等这些UI的配置或描述,也不会去管布局,绘制这些事,它只管自己的那棵树。Element的主要工作都处于渲染流水线的构建(build)阶段。...函数setState()我们很熟悉了。这个函数只是简单执行传入的回调然后调用_element.markNeedsBuild()。你看,如果此时_element为空的时候会不会出问题?...所以建议大家在调用setState()之前用mounted判断一下。另外要注意的一点是,这个函数也是触发渲染流水线的一个点。...我们都知道State有状态,当状态改变时对应的回调函数会被调用。这些回调函数其实都是在StatefulElement里被调用的。

    1.3K10

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

    image.png 如上图,通过源码我们知道: 1、Stream 在 listen 的时候传入了 onData 回调,这个回调会传入到 StreamSubscription 中,之后通过 zone.registerUnaryCallback...相较于 scheduleMicrotask 的异步操作,官方的解释是:在此区域中使用参数执行给定操作并捕获同步错误。...A Stream 的 listen 添加 _handleData 回调,之后在回调里再次调用新的 Current B Stream 的 _handleData 。...二、StreamBuilder 如下代码所示, 在 Flutter 中通过 StreamBuilder 构建 Widget ,只需提供一个 Stream 实例即可,其中 AsyncSnapshot 对象为数据快照...我们常用的 setState 中其实是调用了 markNeedsBuild ,markNeedsBuild 内部标记 element 为 diry ,然后在下一帧 WidgetsBinding.drawFrame

    4K41

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

    了解这个两个概念后,我们先看下图,在 Flutter 中构建一个 Widget ,首先会创建出这个 Widget 的 Element ,而事实上 State 实现跨帧共享,就是将 State 保存在Element...如下图所示,StatefulWidget 的 createState 是在 StatefulElement 的构建方法里创建的, 这就保证了只要 Element 不被重新创建,State 就一直被复用...问题就在于前面 StatefulElement 的构建方法和 update 方法: State 只在 StatefulElement 的构建方法中创建,当我们调用 setState 触发 update...时,只是执行了 _state.widget = newWidget,而我们通过 _DemoPageState(this.data) 传入的 data ,在传入后执行setState 时并没有改变。...我们常说的 setState ,其实是调用了 markNeedsBuild ,markNeedsBuild 内部会标记 element 为 diry,然后在下一帧 WidgetsBinding.drawFrame

    3.7K21

    那些初学者实践 Flutter 最常出现的错误

    哔哩哔哩漫画APP实践Flutter 也有大半年时间了,我针对线上收集到的错误进行分析,挑选出了一些有一般代表性的错误,列在本文,可供实践 Flutter 的初学者们作为一点参考。...典型错误一:无法掌握的Future 典型错误信息:NoSuchMethodError: The method 'markNeedsBuild' was called on null....异步任务结束在页面被pop之后,但没有检查State 是否还是 mounted,继续调用 setState 就会出现这个错误。...又比如,在动画监听的回调里搞点事: @override void initState(){ _animationController.animation.addListener(_handleAnimationTick...); } void _handleAnimationTick() { if (mounted) updateWidget(...); } 同样的在_handleAnimationTick被回调前

    3K21
    领券