Saya memiliki aliran sederhana:

  • a UserModel mengimplementasikan ChangeProvider yang membungkus status pengguna (jika login dan utilitas untuk membuatnya masuk/keluar). Secara khusus logout terlihat seperti:

    void logout() {
       user = null;
       notifyListeners();
    }
    
  • widget UserPage dengan (antara lain):

    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); 
                 }
             )
         }
    }
    

Saya berharap bahwa menekan logout dan memunculkan widget UserPage tidak akan membiarkan flutter membangunnya kembali. Namun tidak demikian dan metode notifyListeners() dalam logout membuat flutter membangun kembali widget dan memicu NullPointerException (karena pengguna adalah null dan email tidak dapat diakses).

Saya bisa mengatasinya (memeriksa apakah objek pengguna adalah != null tetapi saya ingin memahami mengapa ini terjadi).

Apakah benar mengasumsikan pop menghancurkan widget? Jika tidak, bagaimana saya harus menangani kasus ini? Ketika pengguna keluar, saya tidak ingin memiliki widget ini di memori atau berurusan dengan keberadaannya. Saya berharap untuk membuat UserPage ketika pengguna masuk dan menghancurkannya setelah keluar

1
alexlipa 24 Mei 2021, 16:41

1 menjawab

Jawaban Terbaik

Saat Anda memanggil logout , watch di baris ini Text(context.watch<UserModel>().user.email[0]) akan menyebabkan widget itu dibangun kembali.

Anda perlu memanggil logout dalam panggilan balik push yang Anda panggil untuk mendorong halaman ini. pop juga dapat mengirim nilai untuk menginformasikan tentang kondisi seperti keberhasilan atau kegagalan.

Jadi itu akan menjadi seperti ini:

Navigator.pushNamed(context, some_route).then(value) {
context.read<UserModel>().logout();  
}

value dalam panggilan balik dapat dikembalikan dari pop seperti Navigator.of(context).pop(true);

Ini akan memastikan bahwa logout hanya dipanggil setelah widget muncul.

Jika Anda tidak menyukai callback, Anda dapat menggunakan pola async await.

1
moneer alhashim 24 Mei 2021, 14:07