构建期间调用的 setState() 或 markNeedsBuild() - 设置从 API 获取的变量的值时?

Posted

技术标签:

【中文标题】构建期间调用的 setState() 或 markNeedsBuild() - 设置从 API 获取的变量的值时?【英文标题】:setState() or markNeedsBuild() called during build - When setting the value of a variable fetched from an API? 【发布时间】:2020-04-14 11:17:14 【问题描述】:

我这里有一些 json 对象 -


    "error": "0",
    "message": "Got it!",
    "data": [
        
            "status": false,
            "_id": "5e004fc92638d21e5f7e2ffc",
            "group_id": "5dfc7136790365f0955deb2b",
            "date": "2019-12-23T00:00:00.000Z",
            "title": "creating new task",
            "priority": 4,
            "description": "details",
            "tasks": [],
            "created_date": "2019-12-23T05:25:29.524Z",
            "__v": 0
        ,
        
            "status": false,
            "_id": "5e004ff798224784c87baff0",
            "group_id": "5dfc712d790365d5a55deb2a",
            "date": "2019-12-23T00:00:00.000Z",
            "title": "new task",
            "priority": 5,
            "description": "details",
            "tasks": [],
            "created_date": "2019-12-23T05:26:15.621Z",
            "__v": 0
        
    ]

我在这个方法中显示从这些 json 对象中获取的数据 -

  Widget listViewWidget(List<Post> data) 
....

我的应用程序使用PageView 小部件,它以这种方式根据创建日期(“created_date”参数)显示 json 对象 -

。我还定义了一个整数int numberOfTasksLeft;,它应该保存data.length 的值,但每次导航到新页面(上一页或下一页)时我都需要更新它。如果一天有两个 json 对象,整数的值应该是 2,等等。我能得到一个关于如何正确设置这个整数值的建议吗?

我尝试过这样使用 setState 方法 -

  Widget listViewWidget(List<Post> data) 
//settervalue = data;

  setState(() 
    numberofTasks = data.length;
  );

...

但这导致了错误 - setState() or markNeedsBuild() called during build.

【问题讨论】:

【参考方案1】:

Flutter 就像 javascript 先完成同步代码,然后在下一个事件循环中完成异步代码。 setState() or markNeedsBuild() called during build.,发生此错误是因为即使在构建同步完成之前您正在调用setState。因此,如果您在异步块中将调用更改为setState,您就可以解决此问题。不过,也许以一种 hacky 的方式。

Widget listViewWidget(List<Post> data) 

  Timer(Duration(seconds: 0), () 
     setState(() 
       //settervalue = data;
       numberofTasks = data.length;
     );
  );


...

【讨论】:

很好的解释! 欢迎您!这是解决问题的简单方法。【参考方案2】:

定义 PageController 和变量:

PageController controller = PageController();
var currentPageValue = 0.0;

当PageView为scrolled时更新变量。

controller.addListener(() 
  setState(() 
    currentPageValue = controller.page; or //numberofTasks = data.length;
  );
);

【讨论】:

【参考方案3】:

这通常发生在您在调用小部件构建方法之前调用 setState 时。因此请确保在挂载小部件后在 didChangeDependencies() 中设置数据/setState

void didChangeDependencies()


super.didChangeDependencies();
  if(mounted)
    //call setState here

  


【讨论】:

以上是关于构建期间调用的 setState() 或 markNeedsBuild() - 设置从 API 获取的变量的值时?的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

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

错误:在构建期间调用了 setState() 或 markNeedsBuild()

在构建异常期间调用的 setState() 或 markNeedsBuild() 阻止我执行回调