Je refactore le code de mon application Flutter en ajoutant Provider en tant que gestion d'état.
Comportement souhaité: lorsque l'écran d'accueil s'ouvre, l'application doit vérifier si les e-mails des utilisateurs sont vérifiés, si ce n'est pas le cas, la boîte de dialogue s'affiche.
Problème: Cela fonctionnait bien lorsque je transmettais des données pour EmailVerified via le constructeur, mais si je veux utiliser Provider, je ne peux pas obtenir ces données au cycle de vie initState()
.
Pouvez-vous me recommander une approche correcte pour un tel cas d'utilisation?
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 } }
3 Réponses :
Vous devez utiliser le contexte pour appeler Provider.of()
afin que vous puissiez ajouter addPostFrameCallback()
qui est appelé après la première construction, vous pouvez utiliser le contexte
@override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((timeStamp) { auth = Provider.of<Auth>(context, listen: false); }); }
Merci beaucoup @Sebastian. De plus, si quelqu'un d'autre est confronté à ce problème, je recommande l'article suivant, il explique pourquoi showDialog
ne fonctionne pas comme prévu et à quoi sert addPostFrameCallback ()
- didierboelens.com/faq/week2
@ Sebastian Cela fonctionnait sous Android et non sous iOS. Dans iOS lève une erreur Exception non gérée: 'package: provider / src / provider.dart': Échec de l'assertion: ligne 240 pos 12: 'context! = Null': n'est pas vrai. Merci.
Depuis Provider v4.1.0
, vous pouvez également utiliser la méthode read () . Cela réduit le code standard.
@override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((timeStamp) { auth = context.read<Auth>(); }); }
Dans la version 3.0.0 + 1, vous pouvez également faire
tu peux le faire avec
var CallNotifier auth; @override void initState(){ super.initState(); auth = Provider.of<CallNotifier>(context, listen = false); }