在单击带有 setstate 的按钮后,didupdatewidget 不打印。它到底有啥作用?

Posted

技术标签:

【中文标题】在单击带有 setstate 的按钮后,didupdatewidget 不打印。它到底有啥作用?【英文标题】:The didupdatewidget dosen't print after clicking the button with setstate.What does it really do?在单击带有 setstate 的按钮后,didupdatewidget 不打印。它到底有什么作用? 【发布时间】:2019-11-04 21:05:14 【问题描述】:

我正在学习颤振,并且 didupdatewidget 出现在教程中。我真的无法理解它的作用。我已经制作了应用程序,以便在单击按钮后将卡片添加到列中,但在更新卡片列表(产品类)后 didupdatewidget 不打印任何内容。

import 'package:flutter/material.dart';
import './products.dart';

class ProductsManager extends StatefulWidget 
  final String startingproduct;
  ProductsManager(this.startingproduct);
  @override
  State<StatefulWidget> createState() => ProductsManagerState();


class ProductsManagerState extends State<ProductsManager> 
  List<String> _products = [];

  @override
  void initState() 
    super.initState();
    _products.add(widget.startingproduct);
    print("InitState called");


  @override
  void didUpdateWidget(ProductsManager oldWidget) 
    print("Updated the widget");
    super.didUpdateWidget(oldWidget);
 

  @override
  Widget build(BuildContext context) 
    print("build of statefull PM");
    return Column(
      children: <Widget>[
        Container(
          margin: EdgeInsets.all(9.0),
          child: RaisedButton(
            color: Theme.of(context).primaryColor,
            child: Text("data"),
            onPressed: () 
              setState(() 
                print("Setstate called ");
                _products.add("Advanced Food Tester");
              );
            ,
          ),
        ),
        Products(_products)
      ],
    );
  

didupdatewidget 如何显示应用已更新??

【问题讨论】:

【参考方案1】:

据我了解,在状态内调用“setState()”不会调用该状态的 didUpdateWidget()。

但是,如果在 'build()' 方法中此状态返回的小部件是 StatefulWidget(或者如果从此时开始在树下有任何 StatefulWidgets),那么这些 StatefulWidgets 的状态中的 'didUpdateWidget()' 将被调用。

为了理解原因,我们可以看一下flutter在framework.dart中的源码,下面是在State中调用'setState()'时的代码流程粗略总结:

    stateA(say) 调用 'setState()' 在“setState()”中,它调用“_element.markNeedsBuild()”,它将“_element”添加到稍后将由flutter重新构建的脏元素列表中(“_element”只是元素对象StateA 绑定到的,为方便起见,我们将其命名为 elementA) 在下一帧中,flutter 将遍历脏元素列表,并且对于每个元素“元素”,flutter 调用 element.rebuild(),因此将在循环中调用 elementA.rebuild()。 在 elementA.rebuild() 中,它最终调用“built = stateA.build()”,然后调用“updateChild(_child, built)”(其中 _child 是 elementA 在树中的下一个元素,这个“构建”小部件是绑定到)。 updateChild(_child, built) 将小部件“built”设置为元素“_child”的绑定小部件,因此这里是“元素配置更改”发生的地方,因此在元素内调用“didUpdateWidget()” _child'(如果是 StatefulElement)

对于 'didUpdateWidget()',flutter 文档说它是“每当小部件配置更改时调用” 关键思想是stateA中的'setState()'不会重建widgetA,而是重建stateA返回的小部件。因此,“配置更改”发生在返回的小部件上,而小部件A 保持不变。

【讨论】:

以上是关于在单击带有 setstate 的按钮后,didupdatewidget 不打印。它到底有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章

异步功能完成后颤振 setState()

访问 this.state 后如何确保 setState 调用已经执行?

React Switch Input 在第一次单击时未触发 SetState [重复]

Flutter:调用 setState() 方法后不显示 SnackBar

如何只渲染一个 Widget setState

如何将 Material UI 文本字段集中在按钮单击上?