Flutter 提供者和小部件生命周期
Flutter provider and widget lifecycle
我有一个简单的流程:
a UserModel
实现 ChangeProvider
包装用户的状态(如果它已登录并且实用程序记录他 in/out)。特别是注销看起来像:
void logout() {
user = null;
notifyListeners();
}
一个 UserPage
小部件(除其他外):
class UserPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// ... adding only relevant code
// a text with the user first letter of the email
Text(context.watch<UserModel>().user.email[0])
// a logout button with the following onPressed method
TextButton( \ ...
onPressed: () {
context.read<UserModel>().logout();
Navigator.pop(context);
}
)
}
}
我原以为按下注销并弹出 UserPage
小部件不会让 flutter 重建它。然而,情况并非如此, logout
方法中的 notifyListeners()
使 flutter 重建小部件并触发 NullPointerException
(因为用户为空且无法访问电子邮件)。
我可以处理它(检查用户对象是否为 != null 但我想了解为什么会发生这种情况)。
假设 pop
破坏了小部件是否正确?如果没有,我应该如何处理这种情况?
当用户注销时,我不想在内存中保留这个小部件,也不想处理它的存在。我希望在用户登录时创建一个 UserPage
并在注销后将其销毁
当您调用 logout
时,watch
这一行 Text(context.watch<UserModel>().user.email[0])
将导致它所在的小部件重建。
您需要在push
的回调中调用logout
来推送此页面。 pop
也可以发送值来通知成功或失败等条件。
所以它会是这样的:
Navigator.pushNamed(context, some_route).then(value) {
context.read<UserModel>().logout();
}
回调中的 value
可以像这样从 pop
返回 Navigator.of(context).pop(true);
这将确保 logout
仅在弹出小部件后调用。
如果您不喜欢回调,您可以使用 async
await
模式。
我有一个简单的流程:
a
UserModel
实现ChangeProvider
包装用户的状态(如果它已登录并且实用程序记录他 in/out)。特别是注销看起来像:void logout() { user = null; notifyListeners(); }
一个
UserPage
小部件(除其他外):class UserPage extends StatelessWidget { @override Widget build(BuildContext context) { // ... adding only relevant code // a text with the user first letter of the email Text(context.watch<UserModel>().user.email[0]) // a logout button with the following onPressed method TextButton( \ ... onPressed: () { context.read<UserModel>().logout(); Navigator.pop(context); } ) } }
我原以为按下注销并弹出 UserPage
小部件不会让 flutter 重建它。然而,情况并非如此, logout
方法中的 notifyListeners()
使 flutter 重建小部件并触发 NullPointerException
(因为用户为空且无法访问电子邮件)。
我可以处理它(检查用户对象是否为 != null 但我想了解为什么会发生这种情况)。
假设 pop
破坏了小部件是否正确?如果没有,我应该如何处理这种情况?
当用户注销时,我不想在内存中保留这个小部件,也不想处理它的存在。我希望在用户登录时创建一个 UserPage
并在注销后将其销毁
当您调用 logout
时,watch
这一行 Text(context.watch<UserModel>().user.email[0])
将导致它所在的小部件重建。
您需要在push
的回调中调用logout
来推送此页面。 pop
也可以发送值来通知成功或失败等条件。
所以它会是这样的:
Navigator.pushNamed(context, some_route).then(value) {
context.read<UserModel>().logout();
}
回调中的 value
可以像这样从 pop
返回 Navigator.of(context).pop(true);
这将确保 logout
仅在弹出小部件后调用。
如果您不喜欢回调,您可以使用 async
await
模式。