数据未随 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

应该会更新。

根据 docslisten: false 标志允许您从 Provider Store 读取值而无需观察它的变化。它通常用于优化应用程序以避免不必要的重建。