Flutter Widgets 访问 Null Provider 对象

Flutter Widgets Accessing Null Provider Object

我正在开发我的第一个 Flutter 应用程序,但我在使用 Provider 管理应用程序状态的方法上遇到了困难。我已经简化了事情,但胆量是我有一个 AppModel class,它包含一个用户令牌,他们将在经过身份验证后发出 API 请求时使用,以及他们当前的 'team'选择.

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 的消费者 属性。其中,有退出当前团队的选项,因此他们可以选择不同的团队。为此,我将调用 AppModel 中的 exitTeam 函数:

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

这几乎按预期工作。当从 TeamHomeWidget 调用 exitTeam 时,它起作用了。但是,当我在 TeamHomeWidget link 之外的任何其他页面上时,这些页面也是 AppModel 的使用者,我遇到了与 currentTeam 现在为 null 这一事实有关的崩溃。但是,我打算不再呈现这些页面,因为它们应该返回到 SelectTeamWidget。这种做法不对吗?

因为您的 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))));
  }