无法将小部件标记为需要构建,因为该框架已经在构建小部件

时间:2020-03-25 16:19:15

标签: flutter dart flutter-provider

我正在尝试实现Provider,看来它可以正常工作,但我收到此消息:

此_DefaultInheritedProviderScope小部件不能为 标记为需要构建,因为该框架已经在 构建小部件的过程。可以将小部件标记为需要 仅在其祖先之一当前处于构建阶段时构建 建造。允许此异常是因为框架可以构建 父部件在孩子之前,这意味着肮脏的后代会 总是被建造。否则,框架可能无法访问此小部件 在此构建阶段。 setState()或 被称为markNeedsBuild()的是: _DefaultInheritedProviderScope值:“ UserProfile”的实例正在侦听值当前正在使用的小部件 在发出违规呼叫时被构建为:FutureBuilder 脏状态:_FutureBuilderState#bf6ec发生异常时 抛出,这就是堆栈:

0 Element.markNeedsBuild。 (package:flutter / src / widgets / framework.dart:3896:11)

1 Element.markNeedsBuild(package:flutter / src / widgets / framework.dart:3911:6)

2 _InheritedProviderScopeMixin.markNeedsNotifyDependents(package:provider / src / inherited_provider.dart:268:5)

3 ChangeNotifier.notifyListeners(package:flutter / src / foundation / change_notifier.dart:206:21)

4 UserProfile.user =(package:mdd / core / services / user_info.dart:13:5)... UserProfile

发送通知为:“ UserProfile”的实例

我的代码如下:

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final authService = Provider.of<AuthService>(context);
    final userProfile =    Provider.of<UserProfile>(context);

    return StatefulWrapper(
      onInit: () {
        FirebaseNotifications().setUpFirebase();
      },
      child: FutureBuilder<User>(
        future: authService.getUser(),
        builder: (context, AsyncSnapshot<User> snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.error != null) {
              return Text(snapshot.error.toString());
            }
            userProfile.user = snapshot.data;
           // FirebaseUser user = snapshot.data;

            return snapshot.hasData ? ListScreen() : LoginScreen();
          } else {
            return Scaffold(
              appBar: AppBar(),
              body: Container(),
            );
          }
        },
      )
    );
  }
}

这是UserProfile类:

class UserProfile with ChangeNotifier {
  User _user = User();

  get user {
    return _user;
  }

  set user(User user) {
    this._user = user;
    notifyListeners();
  }
}

以及用于获取配置文件的AuthService部分:

Future<User> getUser() async {
  print('GETTING THE USER');
  final fbaseUser = await _auth.currentUser();
  final snapshot = await _db.collection('users')
      .document(fbaseUser.uid)
      .get();
  if (snapshot.data != null) {
    Map<dynamic, dynamic> jsres = snapshot.data;
    _user = User.fromJson(jsres);
    return _user;
  }
}

为什么会出现此错误?我究竟做错了什么?有人可以帮我吗?

2 个答案:

答案 0 :(得分:5)

您可以在下面复制粘贴运行完整的代码,完整的代码可以解决此问题
原因:
此行userProfile.user = snapshot.data;导致错误
FutureBuilder是构建数据,并接收notifyListeners()

根据Flutter小组的建议,https://github.com/flutter/flutter/issues/16218#issuecomment-403995076
FutureBuilder的{​​{1}}应该只构建窗口小部件,不应具有任何逻辑。建造者可以任意打电话。

解决方案:
根据用户情况,在builder之后,您可以直接设置getUser()
步骤1:删除UserProfile.user
步骤2:将final userProfile = Provider.of<UserProfile>(context);逻辑移至userProfile.user = snapshot.data;的{​​{1}}

futureBuilder

完整代码

future

答案 1 :(得分:0)

有问题的代码:

if(condition)
{
  ...
  ...
  notifyListners(); // problem
}else{
  await Future....
  ...
  ...
  notifyListners();  //not getting problem here    
}

带有解决方案的代码:我没有使用 await 这就是为什么会出现错误。所以在异步函数中使用 await,然后再使用 notifyListners()

if(condition)
{
  ...
  ...
  await Future.delayed(Duration(milliseconds: 1)); // use await 
  notifyListners(); 
}else{
  await Future....
  ...
  ...
  notifyListners();      
}