web-dev-qa-db-ja.com

Flutterプロバイダーの状態管理、ログアウトの概念

アプリケーションのカスタムログアウトソリューションを実装しようとしています。ユーザーが現在どこにいても、_Logout button_をクリックすると、アプリは_Login page_に戻ります。

私の考えは、状態の変化をすべてのコンポーネントでリッスンする代わりに、マスターコンポーネントで単一のリスナーを持つことです-> MyApp

簡単にするために、アイテムを最小限に抑えています。これが私のProfileクラスがどのように見えるかです:

_class Profile with ChangeNotifier {
  bool _isAuthentificated = false;
  bool get isAuthentificated => _isAuthentificated;
  set isAuthentificated(bool newVal) {
    _isAuthentificated = newVal;
    notifyListeners();
  }
}
_

Mainの下で、このプロバイダーを次のように登録しました。

_void main() => runApp(
      MultiProvider(
        providers: [
          ChangeNotifierProvider(
            create: (_) => Profile(),
          )
        ],
        child: MyApp(),
      ),
    );
_

そして最後にMyAppコンポーネント:

_class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return Consumer<Profile>(
      builder: (context, profile, _) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            brightness: Brightness.light,
            primaryColor: Color.fromARGB(255, 0, 121, 107),
            accentColor: Color.fromARGB(255, 255, 87, 34),
          ),
          home: buildBasePage(context, profile),
        );
      },
    );
  }

  Widget buildBasePage(BuildContext context, Profile currentProfile) {
    return !currentProfile.isAuthentificated
        ? LoginComponent()
        : MyHomePage(title: 'Flutter Demo Home Page test');
  }
}
_

私の考えは、MyAppコンポーネントはmasterであるため、現在のユーザーが認証された場合に通知され、それに応じて応答するコンシューマーを作成できるはずです。

何が起こるかというと、私がいるときにMyHomePageコンポーネントをクリックして、次のようなLogout()メソッドをクリックします。

_  void _logout() {
    Provider.of<Profile>(context, listen: false).isAuthentificated = false;
  }
_

プロパティを変更すると、最初のMyAppコンポーネントが反応してLoginPageを生成することを期待しています。そうではありません。私はConsumerからProvider.of<Profile>(context, listen: false)に変更しようとしましたが、同じ結果が得られました。

このコンセプトを機能させるには何をする必要がありますか?このようにするのも正しいですか?

つまり、Profileクラスを確実に更新できるということです。つまり、次のメソッドを追加します。

_  logout(BuildContext context) {
    _isAuthentificated = false;

    Navigator.Push(
        context, MaterialPageRoute(builder: (context) => LoginComponent()));
  }
_

そして、単にProvider.of<Profile>(context, listen: false).logout()を呼び出しますが、Providerパッケージはこれ用に設計されていると思いました...または何か不足していますか?

この問題に関するどんな助けでもありがたいです。

4
Robert J.

_listen:false_を渡す必要はありません。代わりに単に呼び出します

Provider.of<Profile>(context).logout()

したがって、Profileクラスは次のようになります。

_      class Profile with ChangeNotifier {
  bool isAuthentificated = false;


  logout() {
    isAuthentificated = false;
    notifyListeners();
  }
}
_
1
Darish