【问题标题】:Flutter provider and widget lifecycleFlutter 提供者和小部件生命周期
【发布时间】:2021-08-12 19:40:23
【问题描述】:

我有一个简单的流程:

  • 一个 UserModel 实现 ChangeProvider ,它包装了用户的状态(如果它已登录并且实用程序让他登录/注销)。特别是注销看起来像:

    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 小部件不会让颤振重建它。但事实并非如此,logout 方法中的notifyListeners() 使颤振重建小部件并触发NullPointerException(因为用户为空且无法访问电子邮件)。

我可以处理它(检查用户对象是否为 != null 但我想了解为什么会发生这种情况)。

假设pop 破坏了小部件是否正确?如果不是,我应该如何处理这种情况? 当用户注销时,我不想在内存中拥有这个小部件,也不想处理它的存在。我希望在用户登录时创建一个UserPage,并在注销后将其销毁

【问题讨论】:

    标签: flutter flutter-provider flutter-state


    【解决方案1】:

    当您调用 logout 时,watch 在这行 Text(context.watch&lt;UserModel&gt;().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 模式。

    【讨论】:

    • 谢谢,你的回答,然后谷歌搜索找到了这个(flutter.dev/docs/cookbook/navigation/returning-data),它有帮助!现在虽然屏幕弹出,然后注销过程(网络调用)开始,然后UserPage 被刷新。有没有办法确保在注销程序完成后显示UserPage 屏幕?
    • 你明白了!假设您正在使用一个屏幕进行登录和用户页面,这些只是一个屏幕,某些状态决定了 UI 将显示什么。在这种情况下,您不需要弹出屏幕,因为通过调用 logout 完成重建就足够了 - 您只需要编写逻辑来处理基于用户状态显示的内容被登录在与否。如果你有单独的屏幕那么你可以使用popAndReplace,但绝对不要弹出,并推送同一个屏幕。
    猜你喜欢
    • 2018-10-13
    • 2010-12-12
    • 1970-01-01
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多