如何在Flutter应用程序的initState期间使用来自Provider的数据

wfveoks0  于 2022-11-25  发布在  Flutter
关注(0)|答案(6)|浏览(173)

我正在通过添加Provider作为状态管理来重构Flutter应用程序代码。

**预期行为:**当主屏幕打开时,应用程序应检查用户电子邮件是否已验证,如果未验证,则应显示弹出对话框。
**问题:**当我通过构造函数为EmailVerified传递数据时,它工作正常,但如果我想使用Provider,我无法在initState()生命周期获得此数据。

您能为我推荐一种正确的使用方法吗?

import 'package:myapp/services/authentication.dart';
import 'package:myapp/screens/settings_screen.dart';
import 'package:flutter/material.dart';
import 'package:myapp/services/authentication.dart';
import 'package:provider/provider.dart';

class HomeScreen extends StatefulWidget {

  @override
  State<StatefulWidget> createState() => new _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  bool _isEmailVerified = false;

  @override
  void initState() {
    super.initState();
    _checkEmailVerification(); // <=== Method which should show Dialog box if email is not verified which is coming from "Auth" Provider
  }

  @override
  Widget build(BuildContext context) {
    final auth = Provider.of<Auth>(context, listen: false); // <==== Service from Provider, which contains data for _isEmailVerified
    auth.isEmailVerified().then((value) => _isEmailVerified = value);

    return new Scaffold(
      appBar: new AppBar(
        title: new Text('My App'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            Text(
              'Welcome to my app',
            ),
          ],
        ),
      ),
    );
  }

  void _checkEmailVerification() async {
    _isEmailVerified = auth.isEmailVerified(); // <=== How can I use "auth" from Provider to get isEmailVerified data ????
    if (!_isEmailVerified) {
      _showVerifyEmailDialog();
    }
  }

  void _showVerifyEmailDialog() {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        // return object of type Dialog
        return AlertDialog(
          title: new Text("Verify your account"),
          content: new Text("Please verify account in the link sent to email"),
          actions: <Widget>[
            new FlatButton(
              child: new Text("Resend link"),
              onPressed: () {
                Navigator.of(context).pop();
                _resentVerifyEmail();
              },
            ),
            new FlatButton(
              child: new Text("Dismiss"),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }

  void _resentVerifyEmail() {
    // Logic to send email
  }
}
35g0bw71

35g0bw711#

您需要使用上下文来调用Provider.of(),以便添加在第一次构建后调用的addPostFrameCallback(),在那里您可以使用上下文

@override
void initState() {
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      auth = Provider.of<Auth>(context, listen: false);
    });
}
6l7fqoea

6l7fqoea2#

Provider v4.1.0开始,你也可以使用read()方法。它减少了样板代码。

@override
void initState() {
  super.initState();

  WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
    auth = context.read<Auth>();
  });
}
nzk0hqpo

nzk0hqpo3#

您可以如下所示创建initState:

''''
 @override
    void initState() {
       super.initState();
       final myModel = Provider.of<YourProivder>(context, listen: false);
  }
''''
bqf10yzr

bqf10yzr4#

您也可以将context传递给HomeScreen小部件,它将允许您访问Provider

class HomeScreen extends StatefulWidget {
  final BuildContext context;
  HomeScreen(this.context);

  @override
  State<StatefulWidget> createState() => new _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool _isEmailVerified = false;

  void _checkEmailVerification() async {
    _isEmailVerified = widget.context.read<Auth>().isEmailVerified();
    if (!_isEmailVerified) {
      _showVerifyEmailDialog();
    }
  }

...

}
hwazgwia

hwazgwia5#

为此,我们需要绑定一个小部件,所以提供商也给予了我们这个功能

WidgetsBinding.instance.addPostFrameCallback((_) {
      auth = Provider.of<Auth>(context, listen: false);
     _isEmailVerified = auth.isEmailVerified()

    });
vs3odd8k

vs3odd8k6#

在版本3.0.0+1中,还可以执行
你可以用

var CallNotifier auth;

@override
void initState(){
 super.initState();
 auth = Provider.of<CallNotifier>(context, listen = false);
}

相关问题