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

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

应用的用例:

main.dart:

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

随机用户提供商:

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 chosenUserIdmain.dart 中,我调用 ProxyProvider

"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。它现在通过自定义 setter/method 传递。

试试这个解决方案

我的代码是这样的

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),
        ),