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

为什么每当类被刷新类调用时,我的initstate就会被调用?

在Flutter中,initState 方法是在一个 StatefulWidget 的生命周期中最早被调用的方法之一。它在 State 对象被插入到组件树中之后立即被调用,并且只被调用一次。如果你发现 initState 在每次类被刷新时都被调用,这通常不是正常的行为,因为 initState 应该只在 State 对象创建时调用一次。

这种情况可能是由于以下原因造成的:

  1. StatefulWidget 被重建:如果你的 StatefulWidget 被重建了,那么新的 State 对象会被创建,从而导致 initState 被再次调用。这可能是因为父组件重新构建,或者是因为你手动调用了 setState 方法。
  2. 路由变化:如果你的应用使用了路由(如 Navigator),当从一个页面导航到另一个页面时,之前的页面的 State 可能会被销毁并重新创建。
  3. 状态管理问题:如果你使用了某种形式的状态管理(如 Provider、Riverpod 等),状态的变化可能导致 widget 树被重建。
  4. 代码逻辑问题:可能在某些地方你错误地重新创建了 StatefulWidget,而不是重用已有的 State。

解决方法

  • 确保 StatefulWidget 的 key 是稳定的:如果你在构建方法中使用了 Key,确保它是稳定的,这样 Flutter 才能正确地识别并重用 State 对象。
代码语言:txt
复制
class MyWidget extends StatefulWidget {
  final Key key;

  MyWidget({required this.key}) : super(key: key);

  @override
  _MyWidgetState createState() => _MyWidgetState();
}
  • 避免不必要的 setState 调用:只在必要时调用 setState,因为它会触发 widget 的重建。
  • 使用稳定的状态管理:如果你使用状态管理库,确保你理解它是如何工作的,并且正确地使用了它。
  • 检查路由逻辑:确保在路由变化时,你没有意外地销毁和重建了 State。

示例代码

代码语言:txt
复制
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('State Management Example'),
        ),
        body: MyWidget(key: ValueKey('unique_key')),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  final Key key;

  MyWidget({required this.key}) : super(key: key);

  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  @override
  void initState() {
    super.initState();
    print('initState called');
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text('Hello World'),
    );
  }
}

在这个例子中,我们为 MyWidget 提供了一个稳定的 Key,这样 Flutter 就可以尝试重用现有的 State 对象,而不是每次都创建一个新的。

如果你遵循了上述建议,但 initState 仍然被多次调用,可能需要进一步检查你的代码逻辑,或者提供更多的上下文信息来确定问题的根源。

参考链接:

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

相关·内容

Flutter 组件 | ValueListenableBuilder 局部刷新小能手

每当监听对象值发生变化时,会触发builder 方法进行刷新。如下,在点击时只需要改变 _counter.value 值,就会触发 _buildWithValue 从而将界面数字刷新。...局部刷新思考 这样实现了局部刷新,可以看出 Build 时间少了很多,比起之前全面刷新就会有所优化。注意,这里很多帧是由于 FloatingActionButton 水波纹效果。...水波纹效果也是在 RawMaterialButton 点击时通过 setState 来刷新实现。这也是另一种局部刷新实现方式:组件分离,将状态变化刷新封装在组件内部,向外界提供操作接口。...比如,现在当进度刷新时,不会触发 _buildTitle 方法,这说明 tag2 之下组件没有构建。...触发 build 方法,从而触发 widget.builder 回,这样实现了局部刷新

8K41
  • 【Flutter】Flutter 页面生命周期 ( 初始化期 | createState | initState | 更新期 | build | 销毁期 | dispose)

    更新期生命周期函数 /// 方法调用时机 : /// ① 调用完 didChangeDependencies 方法后调用该方法 /// ② 调用 setState 方法之后 , 该方法也会被调用...销毁期生命周期函数 /// 方法调用时机 : 该生命周期方法不经常调用 , 只有在组件移除时才调用 /// 该方法在 dispose 方法之前调用 @override void deactivate...调用时机 : 组件销毁时调用 , 要在该方法中进行资源释放与销毁操作 ; /// 7 ....更新期生命周期函数 /// 方法调用时机 : /// ① 调用完 didChangeDependencies 方法后调用该方法 /// ② 调用 setState 方法之后 , 该方法也会被调用...销毁期生命周期函数 /// 方法调用时机 : 该生命周期方法不经常调用 , 只有在组件移除时才调用 /// 该方法在 dispose 方法之前调用 @override void deactivate

    3.5K00

    提到生命周期,我们是在说什么?

    我们可以通过初始化方法,接收父Widget传递过来初始化UI配置参数,这些配置参数决定了Widget最初配置效果 initState,会在State对象插入视图树时候调用,这个函数在State生命周期中只会被调用一次...接下来,和你分析一下这三个方法分别在什么场景下调用。 setState:我们最熟悉方法之一。...当状态数据发生变化时,我们总是通过调用这个方法告诉Flutter:“这儿数据变啦,请使用更新后数据重建UI!”...接下来,我们一起来看一下它们具体调用机制: 当组件可见状态发生变化时,deactivate函数会被调用,这时Sate会被暂时从视图树中移除。...下面这张表格,从功能、调用时机和调用次数维度总结了上面的这些方法,帮助你去理解、记忆: ?

    1.7K10

    Flutter | 和小老弟一起玩转Widget

    setState会导致整个widget全部重建,所以在使用时,我们应该尽量把 子widget 抽离出去,采用局部刷新方式优化,当然这个技巧具体可以百度或者参阅之前代码,并不是什么骚操作,基本入门技巧吧...State生命周期 initState() 当 Widget 第一次插入到 Widget树时调用。对于每一个 State 对象,Flutter framework只会调用一次回。...build() 主要用于构建 Widget 子树时调用,它会在如下场景调用: 在调用 initState 之后 调用 didUpdateWidget 之后 调用 setState 之后 调用 didChangeDependencies...之后 在 State 对象从树中一个位置移除后,又重新插入到树其它位置之后 reassemble() 此回是专门为开发调试而提供,在热重载 (hot reload) 时调用,此回调在 release...下永远不会被调用

    91020

    Flutter中State深入分析理解

    对象创建时候,State.initState方法会被调用; initialized:当State对象创建,但还没有准备构建时,State.didChangeDependencies在这个时候会被调用...; ready:State对象已经准备好了构建,State.dispose没有调用时候; defunct:State.dispose调用后,State对象不能够构建。...create 状态 ,需要注意是此时 是在 StatefulElement 构造函数中执行,之后会在 StatefulElement _firstBuild 方法中回 initState方法...= null; StatefulElement 创建 是在 回 initState方法 之前,如下代码清单1-3 中所示,StatefulElement 继承于 ComponentElement,在父...之后 State 状态 更新 为 ready 状态 ,当前(StatefulElement)回(ComponentElement) _firstBuild 方法 ,在 ComponentElement

    38511

    vue那些原理题?(面试版)

    前言在之前面试时候自己也经常会遇到一些vue原理问题, 也总结了下自己经常用到,方便自己学习,今天也给大家分享出来, 欢迎大家一起学习交流, 有更好方法欢迎评论区指出, 后序也将持续整理总结..., 所以对视图更新做一个异步更新队列,避免重复计算和不必要 DOM 操作,在下一轮时间循环时候刷新队列,并执行已去重任务(nextTick 函数),更新视图export function...p.then(flushCallbacks); // ios 中可能会出现一个回推入微任务队列,但是队列没有刷新情况 // 所以用一个空计时器来强制刷新任务队列 if...pending) { // 如果异步开关是开关上,表示正在执行回函数,然后执行回函数 pending = true; timerFunc(); } // 如果没有提供回...install 方法,调用 install 方法时候,会将 vue 作为参数传入,install 方法同一个插件多次调用时,插件也只会被安装一次作用:注册插件,此时只需要调用 install 方法并将

    62320

    Flutter 绘制探索 6 | 深入分析 CustomPaint 组件 | 七日打卡

    在上面的绘制之后,会调用 _setRasterCacheHints 方法来设置绘制上下文中属性,最后属性设置给 _currentLayer。...CustomPaint size 可能你在使用 CustomPainter#paint 方法内回 size 对象时,有些困惑,为什么有时候会是 Size(0,0),那么这里来一起探索一下回...=null ,会使用孩子size 。这就是所谓 约束自上而下传递,尺寸自下而上设置。 ? 这样,CustomPaint 所有属性,已经介绍完毕,当了解完其内部原来,在使用时就会游刃有余。...当遇到动态绘制和确定画板尺寸时,这些知识会让你有一个最明智决策,而不是乱用setState刷新,或不敢用回 size 进行处理。...---- @张风捷特烈 2021.01.16 未允禁转 公众号:编程之王 联系--邮箱:1981462002@qq.com -- ~ END ~

    1.6K10

    vue这些原理你都知道吗?(面试版)

    前言在之前面试时候自己也经常会遇到一些vue原理问题, 也总结了下自己经常用到,方便自己学习,今天也给大家分享出来, 欢迎大家一起学习交流, 有更好方法欢迎评论区指出, 后序也将持续整理总结..., 所以对视图更新做一个异步更新队列,避免重复计算和不必要 DOM 操作,在下一轮时间循环时候刷新队列,并执行已去重任务(nextTick 函数),更新视图export function...p.then(flushCallbacks); // ios 中可能会出现一个回推入微任务队列,但是队列没有刷新情况 // 所以用一个空计时器来强制刷新任务队列 if...pending) { // 如果异步开关是开关上,表示正在执行回函数,然后执行回函数 pending = true; timerFunc(); } // 如果没有提供回...install 方法,调用 install 方法时候,会将 vue 作为参数传入,install 方法同一个插件多次调用时,插件也只会被安装一次作用:注册插件,此时只需要调用 install 方法并将

    47230

    【源码篇】Flutter Bloc背后思想,一篇纠结文章

    Bloc框架做了一些让非常疑惑操作,_startListening方法中调用了 e.markNeedsNotifyDependents() ,完全没用!...为了验证想法,debug了 framework层notifyClients方法,调用emit或yield刷新时候, _dependentsmap一直为空,哎。。。...emit做了一个判断,如果传入state和存储state对象相同,将不执行刷新操作(这就是在State里面,加clone方法原因) 初始化了Stream一系列对象 封装了关闭Stream流操作...mapEventToState中,然后mapEventToState回传State对象 然后触发listen回,listen中,将state传emit中,然后触发刷新控件重建 总结 上面几个关键分析完...,整个Bloc运行机制,一下子明朗了 BlocProvider 负责储存 传入XxxBloc加以储存 提供of方法,可以在BlocProvider或其子节点位置,获取到储存XxxBloc 提供回收资源

    2.4K41

    【源码篇】Flutter GetX深度剖析 | 我们终将走出自己路(万字图文)

    变量 将自身实例赋值给父Element _inheritedWidgets 变量,key为其widgetruntimeType 为什么任何一个WidgetElement实例 _inheritedWidgets...和传入key相同数据,传入数据将不会被存储 也就是说相同类实例对象,传入并不会被覆盖,只会存储第一条数据,后续放弃 最后使用find方法,返回传入实例 class GetInstance {...; } } 关键步骤 通过泛型获取注入GetXController实例 添加监听代码 addListener:添加监听回 addListenerId:添加监听回,必须设置id,update刷新时候也必须写上配套...,再现俩套经典机制 依赖注入 在做刷新机制前,首先必须写一个依赖注入,我们需要自己管理逻辑层那些实例 这边写了一个极其简单,仅实现三种基础功能:注入,获取,删除 ///依赖注入,外部可将实例,...,自动回收依赖实例是个蛋筒问题,此处写了一个回收控件,可以解决此问题 使用时,必须套一层了;如果大家有更好思路,麻烦在评论里告知 class EasyBindWidget extends StatefulWidget

    4.1K52

    【-Flutter 探索-】AutomaticKeepAliveClientMixin 保持 State 状态

    ---- 然后滑动一下列表,看一下 State 方法回情况。在下滑到底时,可以看到在 13 之后 0 dispose 了,然后前面几个 item 随着滑动逐步 dispose。...是不是感觉很神奇,可能一般介绍文章到这里结束了,毕竟已经解决了问题。但可惜,这是在 bgm 中。...children AutomaticKeepAlive 组件包裹, /// 以便children可以使用 [KeepAliveNotification] 来保存它们状态, /// 否则它们将在屏幕外会被作为垃圾收集...注释说,此方法触发时,表示该组件不再需要保持状态了。...build 中也是确保在 _keepAliveHandle 为 null 时,执行 _ensureKeepAlive,这也是为什么调用 super.build 原因。

    2.1K30

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

    CustomPainter ---- 2.关于 State#setState 只是一把刀,英雄可以拿除暴安良,坏蛋可以拿屠戮无辜。...我会因英雄善举而赞美,也会因坏蛋恶行而唾弃。然而,无法决定自己好坏,毕竟只是一把刀,一个工具。只能祈祷着被他人善用,仅此而已。...Window#scheduleFrame 是一个 native 方法,通过注释可以知道,该方法会在下一次适当时机调用onBeginFrame 和 onDrawFrame 回函数。 ?...所以说无论什么局部刷新,内部原理都和 State#setState 是一样。基本上都是对 setState 一层封装。我们不能因为看不到 State#setState 存在,否定它价值。...现在来终结一下 Custompainter#shouldRepaint 只是在当 RenderCustomPaint 设置画板属性时候才会被

    1.9K20

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

    为什么触发监听逻辑,能导致相应控件刷新?...,只会在第一次build时候触发 这里可以确定_CreateInheritedProvidercreateState方法一定会被调用;接下来看看其方法里面调用 _CreateInheritedProviderState...底下也调用了 startListening,说明从外面传进来这个回调用了,将 上下文实例 和 传进来XxxProvider实例 作为入参传进了这个回中,此处传进来也通过 .call 调用了...performRebuild回中会赋初值 在reassemble回中,_delegateState调用了value( _delegateState.value ) 所以 get value 肯定会在初始化时候调用...BuildContext 每个抽象方法上面注释超级多,删掉了(占篇幅),有兴趣可以自己去源码里看看 BuildContext就是抽象,是约定好一个抽象,相关方法功能已经约定,你如果想实现这个抽象

    1.4K61

    Flutter开发·Flutter中动画实现与使用

    Flutter中动画核心库是Animation,它并不是一个widget,Animation是一个抽象相当于一个定时器,用来描述当前动画开始,暂停,以及数值状态,与ui渲染没有任何关系,它不能直接控制...:为动画添加一个屏幕刷新,每次屏幕刷新都会调用TickerCallback,目的是使用Ticker来驱动动画会防止屏幕外动画(动画UI不在当前屏幕时,如锁屏时)消耗不必要资源。...为这个控制器添加listener监听,每次控制器value发生改变时监听中都会收到回。...前面说Animation不负责ui变化,所以这里要在监听中调用setState方法使得ui可以响应到控制器数值变化。...Tween中提供了两个泛型参数begin和end,也就是你可以指定你要进行变化属性值,比如有很多Flutter中已经封装好继承自Tween补间动画:ColorTween,SizeTween,BorderTween

    1.5K00

    用两张图告诉你,为什么App会卡顿?

    这个布局到底添加到哪了?天,知识点来了! 可能很多同学也知道这个布局是放到了一个叫做DecorView父布局里,但是还是要再说一遍。且看下图。 ?...WindowManagerImpl自然就是接口WindowManager一个实现喽。这一点是没有在图中反映。...这也就是为什么前面提到过,WindowManager只是一个代理,实际管理功能是通过WindowManagerGlobal实现。我们来看个源码例子比较清晰了。开始啦!...} FrameCallback一旦注册,那么每次收到Vsync信号时它都会被。利用它,我们可以实现会帧率监听。...doTraversal()调用时,一系列测量、布局和绘制操作开始了。

    90630

    Flutter--Flutter中Widget、App生命周期

    其生命周期流程图则如下所示,下图中所有方框都是StatefulWidget中可以重写方法,这些方法在响应生命周期状态下会被自动回。 ?...State,当组件从组件树中移除,然后重新插入到组件树中时, createState 函数将会被调用创建一个新 State。...1.2.2 生命周期二:initState initState 函数在组件插入树中时 Framework 调用(在 createState 之后),此函数只会被调用一次,子类通常会重写此方法,在其中进行初始化操作...另外,当此 State 对象依赖项更改时调用,比如其所依赖 InheritedWidget 发生变化时, Framework 会调用此方法通知组件发生变化。...为什么要加上如此判断?因为如果当前组件未插入到树中或者已经从树中移除时,调用 setState 会抛出异常,加上 mounted 判断,则表示当前组件在树中。

    2.9K31
    领券