繁体   English   中英

Flutter - ProxyProvider 如何修复错误“Null check operator used on a null value”

[英]Flutter - ProxyProvider how to fix error "Null check operator used on a null value"

应用程序用例:

  • 在 App 启动时,它会从 RestAPI 中获取一个随机用户,
  • 然后它将使用第一次调用的结果进行另一个 RestAPI 调用,这就是我需要 ProxyProvider 的原因。

main.dart:

return MultiProvider(
    providers: [
      ChangeNotifierProvider(
        create: (_) => RandomUser(),
      ),
      ChangeNotifierProxyProvider<RandomUser, FavoriteList>(
        create: (BuildContext ctx) => FavoriteList(ctx.read<RandomUser>()),
        update: (_, RandomUser user, __) => FavoriteList(user),
      ),

RandomUser 提供者:

class RandomUser extends ChangeNotifier {
  final apiUsers = UsersApi();
  UserModel? _profile;
  String? _userId;

  RandomUser() {
    fetchUser();
  }

  Future<void> fetchUser() async {
    await apiUsers
      .apiGetUser()
      .then((user) => {
        _profile = user,
        _userId = chosenUserId,
      })
      .catchError((e) {
        print("error: $e");
    });

    notifyListeners();
  }

  UserModel get profile => _profile;

  String get chosenUserId => _userId;
}

收藏列表提供者:

class FavoriteList extends ChangeNotifier {
  final RandomUser _user;
  final _apiFavoriteList = FavoriteListApi();
  List<FavoriteListModel> _favoriteList = <FavoriteListModel>[];

  FavoriteList(this._user) {
    fetchFavoriteList(_user.chosenUserId);
  }

  Future<void> fetchFavoriteList(String userId) async {
   await _apiFavoriteList
      .apiGetFavoriteList(userId)
      .then((favoriteList) => {
        _favoriteList = favoriteList,
      })
      .catchError((e) {
        print("error: $e");
    });

    notifyListeners();
  }
  
  List<FavoriteListModel> get favoriteList => this._favoriteList;
}

如您所见, FavoriteList provider需要RandomUser provider来检索 getter 值chosenUserId

当我启动应用程序时,我立即在 getter selectedUserId 和chosenUserId上收到错误“Null check operator used on a ProxyProvider value”,我在其中调用main.dart"create"

我究竟做错了什么? ProxyProvider不应该首先初始化第一个Provider ,所以我需要的所有值都可用吗?

问题是RandomUser.fetchUser()在创建FavoriteList之前尚未完成。 您应该编写允许这种情况的代码,例如在RandomUser中:

  String? get chosenUserId => _userId;

并在FavoriteList中:

  final? RandomUser _user;

  FavoriteList(this._user) {
    if (_user != null && _user?.chosenUserId != null) {
      fetchFavoriteList(_user.chosenUserId);
    }
  }

  String? get chosenUserId => _user?.chosenUserId;

fetchUser()完成时, FavoriteList将被更新。

当然,您的 UI 将不得不处理(临时)丢失的数据。

顺便说一句, ChangeNotifierProxyProvider的文档建议您应该像这样构造代码:

ChangeNotifierProxyProvider<MyModel, MyChangeNotifier>(
  create: (_) => MyChangeNotifier(),
  update: (_, myModel, myNotifier) => myNotifier
    ..update(myModel),
  child: ...
);

在这种情况下,如果要更新 MyModel,那么 MyChangeNotifier 将能够相应地更新。 请注意 MyChangeNotifier 如何不再在其构造函数中接收 MyModel。 它现在通过自定义设置器/方法传递。

试试这个解决方案

我的代码是这样的

providers: [
        ChangeNotifierProvider(create: (ctx) => Auth()),
        ChangeNotifierProxyProvider<Auth, Products>(
          create: (ctx) => Products(null, null, []),
          update: (ctx, auth, previousProducts) => Products(
              auth.token! ,
              auth.userId! ,
              previousProducts == null ? [] : previousProducts.items),
        ),
        ChangeNotifierProvider(create: (ctx) => Cart()),
        ChangeNotifierProxyProvider<Auth, Orders>(
          create: (ctx) => Orders(null, null, []),
          update: (ctx, auth, previousOrders) {
            print(auth);
            return Orders(auth.token!, auth.userId!,
                previousOrders == null ? [] : previousOrders.orders);
          },
        ),
      ],

并通过改变来解决这个问题! ?? 喜欢这段代码

ChangeNotifierProxyProvider<Auth, Products>(
          create: (ctx) => Products(null, null, []),
          update: (ctx, auth, previousProducts) => Products(
              auth.token ?? null,
              auth.userId ?? null,
              previousProducts == null ? [] : previousProducts.items),
        ),

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM