Flutter State生命周期

介绍

State生命周期是一个经常会问到的问题,掘金的文章有很多相关的文章,码这篇文章记录一下自己的学习过程。想要了解清楚,最好还是认真的看源码,大佬的文章有时候会难懂,但是只有真正了解细节才能变成自己的东西。

前言

State最开始的理解是保存状态,但是Widget本身是不可变的,这意味着Widget是轻量级的,会被频繁的创建与销毁,那么StateFulWidget是如何保存状态的呢。

在上一篇文章中我们了解了ELement、ComponentElement、StatelessElement调用的方法以及更新的机制,如果canupdate判断相同的情况下element复用,结合State会保持状态,我们判断State与Element关联,下面来看看源码

StatefulElment

StatefulElement(StatefulWidget widget)
      : _state = widget.createState(),
        super(widget) {
    _state._element = this;
    _state._widget = widget;
  }
复制代码

StatefulElement中定义_state变量并持有,_state又持有elementwidget

_firstBuild

@override
  void _firstBuild() {
    assert(_state._debugLifecycleState == _StateLifecycle.created);
    try {
      final dynamic debugCheckForReturnedFuture = _state.initState() as dynamic;
    } finally {
    }
  
    _state.didChangeDependencies();
    
    super._firstBuild();
  }
复制代码

可以看到_firstBuild调用了initState和didChangeDependencies,最后调用super._firstBuild(),super是指ComponentElementsuper._firstBuild()最终调用rebuild()

performRebuild

  @override
  void performRebuild() {
    if (_didChangeDependencies) {
      _state.didChangeDependencies();
      _didChangeDependencies = false;
    }
    super.performRebuild();
  }
复制代码

performRebuild方法调用super.performRebuild=>build(),updateChild,更新child,中间我们看到_state.didChangeDependencies(),其实可以推断出来是inherited共享组件数据变化时,rebuild调用了_state.didChangeDependencies(),以后有机会可以记录一下inherit

update

StatefulElement#update
  @override
  void update(StatefulWidget newWidget) {
    super.update(newWidget);
    final StatefulWidget oldWidget = _state._widget;
    _dirty = true;
    _state._widget = widget as StatefulWidget;
    try {
      final dynamic debugCheckForReturnedFuture = _state.didUpdateWidget(oldWidget) as dynamic;
    } finally {
    }
    rebuild();
  }
复制代码
Element#update
@mustCallSuper
  void update(covariant Widget newWidget) {
    _widget = newWidget;
  }
复制代码

rebuild()递归遍历childStatelessElement逻辑相同,中间调用_state.didUpdateWidget,所以什么时候didUpdateWidget我们可以得出结论:element复用的时候,如果element没有被复用就不会调用didUpdateWidget

结论

具体有张图可以参考

4b1bcc3a2bd94c0fb92de8ed08ef4e58_tplv-k3u1fbpfcp-watermark.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享