如何在 Flutter 应用程序的 initState 期间使用来自 Provider 的数据
How to use data from Provider during initState in Flutter application
我正在通过添加 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
}
}
你需要使用上下文来调用Provider.of()
,所以你可以添加addPostFrameCallback()
,它在第一次构建后调用,在那里你可以使用上下文
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
auth = Provider.of<Auth>(context, listen: false);
});
}
从Provider v4.1.0
开始,您也可以使用read()方法。它减少了样板代码。
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
auth = context.read<Auth>();
});
}
3.0.0+1版本还可以
你可以用
var CallNotifier auth;
@override
void initState(){
super.initState();
auth = Provider.of<CallNotifier>(context, listen = false);
}
您还可以将 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();
}
}
...
}
您可以按如下方式设置您的 initState:
''''
@override
void initState() {
super.initState();
final myModel = Provider.of<YourProivder>(context, listen: false);
}
''''
我正在通过添加 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
}
}
你需要使用上下文来调用Provider.of()
,所以你可以添加addPostFrameCallback()
,它在第一次构建后调用,在那里你可以使用上下文
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
auth = Provider.of<Auth>(context, listen: false);
});
}
从Provider v4.1.0
开始,您也可以使用read()方法。它减少了样板代码。
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
auth = context.read<Auth>();
});
}
3.0.0+1版本还可以
你可以用
var CallNotifier auth;
@override
void initState(){
super.initState();
auth = Provider.of<CallNotifier>(context, listen = false);
}
您还可以将 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();
}
}
...
}
您可以按如下方式设置您的 initState:
''''
@override
void initState() {
super.initState();
final myModel = Provider.of<YourProivder>(context, listen: false);
}
''''