每次单击登录按钮时都会重建登录小部件

Posted

技术标签:

【中文标题】每次单击登录按钮时都会重建登录小部件【英文标题】:Sign In widget is rebuilt everytime sign in button is clicked 【发布时间】:2021-06-09 11:23:47 【问题描述】:

AuthProvide 类*

class AuthProvider extends ChangeNotifier 

  final FirebaseAuth _auth = FirebaseAuth.instance;

  bool get isSignedIn => _auth.currentUser != null;

  User get currentUser => _auth.currentUser!;

  String message = '';

  Future<String> signIn(
      required String email, required String password) async 
    try 
      await _auth.signInWithEmailAndPassword(email: email, password: password);
      notifyListeners();
      message = 'Successfully signed in';
      return message;
     on FirebaseAuthException catch (e) 
      message = getMessageFromErrorCode(e.code);
      return message;
    
  

我使用消费者在 main 中调用 isSignedIn getter,并根据 bool 值返回登录屏幕或主屏幕。

登录小部件

                  SignInBar(
                    label: 'Sign in',
                    color: const Color(0xff092E34),
                    onPressed: () async 
                      FocusScope.of(context).unfocus();
                      if (_formKey.currentState!.validate()) 
                        _formKey.currentState!.save();
                        String message = await context
                            .read<AuthProvider>()
                            .signIn(email: _email, password: _password);
                        SnackBar snackBar = SnackBar(content: Text(message));
                        ScaffoldMessenger.of(context).showSnackBar(snackBar);
                      
                    ,
                  ),

当 SignIn onPressed 被调用时,我的小部件被重建并且表单被清除。如何阻止它重建?

【问题讨论】:

【参考方案1】:

好的,所以我不知道上述问题的具体原因,但我尝试了一种不同的身份验证提供程序方法,它确实解决了我的问题。 我将其发布在答案中是因为我想与所有人共享此身份验证提供程序模板,因为我在寻找具有空安全性的模板时遇到了很多问题。

身份验证提供者

class AuthProvider with ChangeNotifier 
  bool _isLoading = false;
  bool get isLoading => _isLoading;

  FirebaseAuth firebaseAuth = FirebaseAuth.instance;

  Future<String?> register(String email, String password) async 
    setLoading(true);
    try 
      UserCredential authResult = await firebaseAuth
          .createUserWithEmailAndPassword(email: email, password: password);
      User? user = authResult.user;
      setLoading(false);
      notifyListeners();
      return user != null ? null : 'An error Occurred';
     on SocketException 
      setLoading(false);
      notifyListeners();
      return "No internet, please connect to internet";
     on FirebaseAuthException catch (e) 
      setLoading(false);
      notifyListeners();
      return e.message;
    
  

  Future<String?> login(String email, String password) async 
    setLoading(true);
    try 
      UserCredential authResult = await firebaseAuth.signInWithEmailAndPassword(
          email: email, password: password);
      User? user = authResult.user;
      setLoading(false);
      notifyListeners();
      return user != null ? null : 'An error Occurred';
     on SocketException 
      setLoading(false);
      notifyListeners();
      return "No internet, please connect to internet";
     on FirebaseAuthException catch (e) 
      setLoading(false);
      notifyListeners();
      return e.message;
    
  

  Future logout() async 
    await firebaseAuth.signOut();
  

  void setLoading(val) 
    _isLoading = val;
    notifyListeners();
  

  Stream<User?> get user =>
      firebaseAuth.authStateChanges().map((event) => event);

Main.dart

MultiProvider(
            providers: [
              ChangeNotifierProvider<AuthProvider>.value(value: AuthProvider()),
              StreamProvider<User?>.value(
                value: AuthProvider().user,
                initialData: null,
              )
            ],
            child: MaterialApp(
              title: 'Revora',
              debugShowCheckedModeBanner: false,
              theme: ThemeData(
                visualDensity: VisualDensity.adaptivePlatformDensity,
                primarySwatch: Colors.teal,
                accentColor: Colors.amber,
                textTheme: AppTheme.textTheme,
                appBarTheme: AppBarTheme(
                  backgroundColor: Colors.white,
                  elevation: 0.0,
                ),
                platform: TargetPlatform.android,
              ),
              home: Wrapper(),
            ),
          );

如果这有帮助,请为答案投票,以便每个人都可以从中受益。

【讨论】:

以上是关于每次单击登录按钮时都会重建登录小部件的主要内容,如果未能解决你的问题,请参考以下文章

在pyqt5中单击登录按钮时获取小部件未定义错误

在路由后,TextField单击重建/重新加载小部件

ActivityNotFoundException 意图 + 小部件

在 Qt 中使用按钮堆叠小部件页面

如何调用无状态小部件的重建?

当消费者触发重建时,MaterialApp 主页小部件不会被渲染。需要油漆