Flutter - ProxyProvider 如何修复错误 "Null check operator used on a null value"
Flutter - ProxyProvider how to fix error "Null check operator used on a null value"
应用的用例:
- 在应用程序启动时,它会从 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),
),
随机用户提供商:
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 chosenUserId
和 main.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),
),
应用的用例:
- 在应用程序启动时,它会从 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),
),
随机用户提供商:
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 chosenUserId
和 main.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),
),