首页 > 解决方案 > Flutter Widgets 访问 Null Provider 对象

问题描述

我正在开发我的第一个 Flutter 应用程序,并且在使用 Provider 管理应用程序状态的方法上遇到了困难。我已经简化了一些事情,但最重要的是我有一个 AppModel 类,其中包含一个用户令牌,一旦通过身份验证,他们将在发出 API 请求时使用该用户令牌,以及他们当前的“团队”选择。

class AppModel extends ChangeNotifier {
  Team _team;
  Team get currentTeam => _team;

  String _userToken;
  String get userToken => _userToken;

  void setUser({String token, Team team}) {
    _userToken = token;
    _team = team;
    notifyListeners();
  }

  void exitTeam() {
    _team = null;
    notifyListeners();
  }
}

有用户可以定位的主要位置。如果他们的 userToken 为空,他们应该被带到登录页面。如果他们有一个 userToken,但 currentTeam 为空,他们应该在团队选择屏幕上。如果他们有一个团队,他们就在一组页面中,他们可以从“TeamHomePage”小部件开始管理该团队。在顶层,我有以下小部件构建功能:

  @override
  Widget build(BuildContext context) {
    return Consumer<AppModel>(
        builder: (context, model, _) => (model?.userToken?.isEmpty ?? true
            ? LoginScreen()
            : (model.currentTeam == null
                ? SelectTeamWidget(userToken: model.userToken)
                : TeamHomeWidget())));
  }

在 TeamHomeWidget 中,还有其他页面是 AppModel 的消费者,它们查看 currentTeam 属性。其中,有退出当前团队的选项,以便他们可以选择不同的团队。为此,我在 AppModel 中调用 exitTeam 函数,如下所示:

Provider.of<AppModel>(context, listen: false).exitTeam();

这几乎按预期工作。从 TeamHomeWidget 调用 exitTeam 时,它可以工作。但是,当我在链接出 TeamHomeWidget 且也是 AppModel 消费者的任何其他页面上时,我会遇到与 currentTeam 现在为空的事实相关的崩溃。但是,我打算不再呈现这些页面,因为它们应该被带回 SelectTeamWidget。这种方法不正确吗?

标签: flutterflutter-provider

解决方案


由于您的TeamHomeWidget 也包含有 Consumer并使用 currentTeam 做某事。这个 Consumer 也在监听 AppModel 的变化,如果这个 Consumer 的触发速度比你的顶级 Consumer Widget 快,那么你的应用就会崩溃。

为防止这种情况,请将顶层中的值分配给 TeamHomeWidget

 @override
  Widget build(BuildContext context) {
    return Consumer<AppModel>(
        builder: (context, model, _) => (model?.userToken?.isEmpty ?? true
            ? LoginScreen()
            : (model.currentTeam == null
                ? SelectTeamWidget(userToken: model.userToken)
                : TeamHomeWidget(team: model.currentTeam))));
  }

推荐阅读