【问题标题】:Flutter: setState() or markNeedsBuild() called during build with ProviderFlutter:在使用 Provider 构建期间调用 setState() 或 markNeedsBuild()
【发布时间】:2020-06-29 06:22:15
【问题描述】:

我正在从initState() 方法调用ChangeNotifier 函数之一,而函数内部的notifyListener() 调用正在抛出 setState() or markNeedsBuild() called during build.异常

void initState(){
 Provider.of<MessengerRepository>(context, listen: false).setUnreadCount(0);
 super.initState();
}
class MessengerRepository with ChangeNotifier {
  int unreadCount;
  void setUnreadCount(int value){
     unreadCount = value;
     notifyListeners();
}

我需要在setUnreadCount() 中调用notifyListener(),因为我在执行期间在多个位置调用setUnreadCount() 函数。所以不能只删除notifyListener()里面的initState()

使用provider 4.0.4 版

【问题讨论】:

    标签: flutter flutter-provider


    【解决方案1】:

    日志消息中提到的这个问题的原因是initState() 中的函数正在通过notifyListener() 请求重建(如果我们也使用setState(),也会发生同样的情况)甚至在第一次构建之前完成。

    解决方案是添加一个addPostFrameCallback,并在其中执行重建功能,这样它只会在第一次构建小部件后执行

    void initState() {
        super.initState();
        WidgetsBinding
          .instance
          .addPostFrameCallback(
              (_) => Provider.of<MessengerRepository>(context, listen: false).setUnreadCount(0)
        );
      }
    

    【讨论】:

      【解决方案2】:

      您可以将 Provider.of&lt;MessengerRepository&gt;(context, listen: false).setUnreadCount(0);intState 移动到 didChangeDependecies 然后它只会在页面完成构建过程后被调用。

      或者通过这种方式:(不太优雅)

      void setUnreadCount(int value, {bool shouldUpdate: true}){
           unreadCount = value;
         if(shouldUpdate)  notifyListeners();
      

      然后

      void initState(){
       Provider.of<MessengerRepository>(context, listen: false).setUnreadCount(0, shouldUpdate:false);
       super.initState();
      }
      

      当您在 initState 中调用它时,如果构建方法在您的所有变量(重新)分配之前完成,它们将不会被更新,直到您调用 setStatenotifyListeners

      Learn more here

      【讨论】:

        猜你喜欢
        • 2020-08-11
        • 2020-04-10
        • 2021-11-25
        • 2020-12-12
        • 2020-12-28
        • 2021-01-06
        • 2021-05-31
        • 2021-08-24
        相关资源
        最近更新 更多