数据未随 Provider、Flutter 更新
Data not updating with Provider, Flutter
用户更改数据后,UI不会用Provider
更新数据。 API 调用总是 statusCode: 200
但 UI 不会更新,除非我再次 refresh/build 页面。我假设我没有正确设置设置状态方法,但我不确定我做错了什么。代码:
编辑资料信息的方法:
Map<String, dynamic> userData;
@override
Widget build(BuildContext context) {
UserData user = UserData.fromJson(userData);
return TextButton(
onPressed: () async {
changeUserInfo(user) // I pass the user object to the method
.whenComplete(() => Navigator.of(context).pop());
},
child: Text(
'SAVE',
),
);
}
更改用户方法:
Future<void> changeUserInfo(UserData user) async {
final userRes = await patchUserInfo(user); // API CALL WHICH ALWAYS GOES THROUGH
if (userRes != null) {
// HERE IS WHERE I WANT TO SET THE CURRENT STATE OF THE USER THAT HAS BEEN CHANGED
userStore.setUserInfo(user);
return;
}
}
用户存储:
class UserStore extends ChangeNotifier {
Map<String, UserData> _userInfo = {};
Map<String, UserData> get userInfo => _userInfo ;
void setUserInfo(UserData user) {
_userInfo[user.id] = user; // I assume this is where I do something wrong?!
notifyListeners();
}
UserData getUserInfoByUserId(String userId) => _userInfo[userId];
}
补丁后返回的 API 中的 JSON:
{
"statusCode": 200,
"message": "Success",
"data": {
"id": "1",
"email": "johndoe@johndoe.com",
"firstName": "John",
"lastName": "Doe",
}
}
我的用户模型:
class UserData {
String id, firstName,
lastName,
email;
UserData({
this.id,
this.firstName,
this.lastName,
this.email,
});
UserData.fromJson(Map<String, dynamic> json) {
id = json['id'];
firstName = json['firstName'];
lastName = json['lastName'];
email = json['email'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['id'] = this.id;
data['firstName'] = this.firstName;
data['lastName'] = this.lastName;
data['email'] = this.email;
return data;
}
}
假设我应该看到更改的屏幕(我什至尝试使用 Consumer
,所以它是一样的):
class SomeClassExample extends StatelessWidget {
final userStore = Provider.of<UserStore>(context, listen: false);
UserData user = userStore.getUserInfo(userId);
...
return Column(
children: [
Text(user.firstName),
Text(user.lastName),
],
);
}
现在设置的方式(或者至少我是这么认为的),我把user
对象传给了changeUserInfo
方法,这里把对象传给了API调用,如果返回的 API 调用不是 null
,则使用传递的对象设置用户信息的当前状态。然后在商店中,我将该对象传递到我的 UserData
地图中,通知听众,在收听的地方更新它,仅此而已。我不确定我做错了什么。
在此先感谢您的帮助。
为什么不将 Column 包装在 Consumer 小部件中,该小部件监听 UserStore.
你是这样做的吗:
// remove fetching the provider using Provider.of;
// the Consumer widget is taking care of that for you.
return Consumer<UserStore>(
builder: (context, userStore, child) {
UserData user = userStore.getUserInfo(userId);
return Column(
children: [
Text(user.firstName),
Text(user.lastName),
],
);
}
);
每次您在 UserStore 上调用 notifyListeners 时,它应该会导致此小部件自行重建,显示更改。
现在,您也没有显示从哪里获得 userId,我现在也想知道这一点。
您突出显示的行
您的 JSON 和您的 UserData 对象使用 UserData.id
成员,但突出显示 _userInfo[user.userId] = user;
的行使用 userId
。如果提供的 class 定义是正确的,那么它应该是 user.id
.
其他提供商的东西,也许
您可以使用 context.watch 而不是 Provider.of,但是如果 Consumer 不工作,那么它不可能改变任何东西。 (代码块中编写的提供程序不会触发 re-render)
final userStore = context.watch<UserStore>();
UserData user = userStore.getUserInfo(userId);
...
return Column(
children: [
Text(user.firstName),
Text(user.lastName),
],
);
记得将 Provider 插入 Widget Tree
也许要确保 Provider 已正确插入到小部件树中 - 上面的代码示例不包含确切的代码。如果它丢失了,那么它应该是什么样子的近似值如下:
ChangeNotifierProvider(create: (context) => UserStore(), SomeParentWidget())
在这一行:
final userStore = Provider.of<UserStore>(context, listen: false);
改用listen: true
。
应该会更新。
根据 docs,listen: false
标志允许您从 Provider Store 读取值而无需观察它的变化。它通常用于优化应用程序以避免不必要的重建。
用户更改数据后,UI不会用Provider
更新数据。 API 调用总是 statusCode: 200
但 UI 不会更新,除非我再次 refresh/build 页面。我假设我没有正确设置设置状态方法,但我不确定我做错了什么。代码:
编辑资料信息的方法:
Map<String, dynamic> userData;
@override
Widget build(BuildContext context) {
UserData user = UserData.fromJson(userData);
return TextButton(
onPressed: () async {
changeUserInfo(user) // I pass the user object to the method
.whenComplete(() => Navigator.of(context).pop());
},
child: Text(
'SAVE',
),
);
}
更改用户方法:
Future<void> changeUserInfo(UserData user) async {
final userRes = await patchUserInfo(user); // API CALL WHICH ALWAYS GOES THROUGH
if (userRes != null) {
// HERE IS WHERE I WANT TO SET THE CURRENT STATE OF THE USER THAT HAS BEEN CHANGED
userStore.setUserInfo(user);
return;
}
}
用户存储:
class UserStore extends ChangeNotifier {
Map<String, UserData> _userInfo = {};
Map<String, UserData> get userInfo => _userInfo ;
void setUserInfo(UserData user) {
_userInfo[user.id] = user; // I assume this is where I do something wrong?!
notifyListeners();
}
UserData getUserInfoByUserId(String userId) => _userInfo[userId];
}
补丁后返回的 API 中的 JSON:
{
"statusCode": 200,
"message": "Success",
"data": {
"id": "1",
"email": "johndoe@johndoe.com",
"firstName": "John",
"lastName": "Doe",
}
}
我的用户模型:
class UserData {
String id, firstName,
lastName,
email;
UserData({
this.id,
this.firstName,
this.lastName,
this.email,
});
UserData.fromJson(Map<String, dynamic> json) {
id = json['id'];
firstName = json['firstName'];
lastName = json['lastName'];
email = json['email'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['id'] = this.id;
data['firstName'] = this.firstName;
data['lastName'] = this.lastName;
data['email'] = this.email;
return data;
}
}
假设我应该看到更改的屏幕(我什至尝试使用 Consumer
,所以它是一样的):
class SomeClassExample extends StatelessWidget {
final userStore = Provider.of<UserStore>(context, listen: false);
UserData user = userStore.getUserInfo(userId);
...
return Column(
children: [
Text(user.firstName),
Text(user.lastName),
],
);
}
现在设置的方式(或者至少我是这么认为的),我把user
对象传给了changeUserInfo
方法,这里把对象传给了API调用,如果返回的 API 调用不是 null
,则使用传递的对象设置用户信息的当前状态。然后在商店中,我将该对象传递到我的 UserData
地图中,通知听众,在收听的地方更新它,仅此而已。我不确定我做错了什么。
在此先感谢您的帮助。
为什么不将 Column 包装在 Consumer 小部件中,该小部件监听 UserStore.
你是这样做的吗:
// remove fetching the provider using Provider.of;
// the Consumer widget is taking care of that for you.
return Consumer<UserStore>(
builder: (context, userStore, child) {
UserData user = userStore.getUserInfo(userId);
return Column(
children: [
Text(user.firstName),
Text(user.lastName),
],
);
}
);
每次您在 UserStore 上调用 notifyListeners 时,它应该会导致此小部件自行重建,显示更改。 现在,您也没有显示从哪里获得 userId,我现在也想知道这一点。
您突出显示的行
您的 JSON 和您的 UserData 对象使用 UserData.id
成员,但突出显示 _userInfo[user.userId] = user;
的行使用 userId
。如果提供的 class 定义是正确的,那么它应该是 user.id
.
其他提供商的东西,也许
您可以使用 context.watch 而不是 Provider.of,但是如果 Consumer 不工作,那么它不可能改变任何东西。 (代码块中编写的提供程序不会触发 re-render)
final userStore = context.watch<UserStore>();
UserData user = userStore.getUserInfo(userId);
...
return Column(
children: [
Text(user.firstName),
Text(user.lastName),
],
);
记得将 Provider 插入 Widget Tree
也许要确保 Provider 已正确插入到小部件树中 - 上面的代码示例不包含确切的代码。如果它丢失了,那么它应该是什么样子的近似值如下:
ChangeNotifierProvider(create: (context) => UserStore(), SomeParentWidget())
在这一行:
final userStore = Provider.of<UserStore>(context, listen: false);
改用listen: true
。
应该会更新。
根据 docs,listen: false
标志允许您从 Provider Store 读取值而无需观察它的变化。它通常用于优化应用程序以避免不必要的重建。