Flutter setState导致无限渲染

时间:2020-07-30 13:01:57

标签: flutter

import 'package:flutter/material.dart';
import 'package:myfitnesstrainer/logic/firestore_services.dart';
import 'package:myfitnesstrainer/models/user.dart';
import 'package:myfitnesstrainer/models/user_repository.dart';
import 'package:myfitnesstrainer/screens/loading_screen.dart';
import 'package:provider/provider.dart';

class DistributePage extends StatefulWidget {
  // final User currentUser;
  const DistributePage();

  @override
  _DistributePageState createState() => _DistributePageState();
}

class _DistributePageState extends State<DistributePage> {
      FirestoreServices _firestoreServices = new FirestoreServices();
    bool isLoading=true;
    User curUser= new User();
    
    Future<User> getGoogleContent(UserRepository auth) async {
    var auth_user = await auth.getUser();
    print(auth_user.uid); //This print
    curUser.userID = auth_user.uid;
    curUser.name = auth_user.displayName;
    curUser.email = auth_user.email;
    curUser.imageUrl = auth_user.photoUrl;
    curUser =await _firestoreServices.saveUser(curUser);
   setState(() {
          isLoading = false;
          
    });

    return curUser;
  }
  @override
  Widget build(BuildContext context) {
    UserRepository auth = Provider.of<UserRepository>(context);
    getGoogleContent(auth);

    void logout() async {
      await auth.signOut();
    }

    return  isLoading ? LoadingScreen() :  Scaffold(appBar:AppBar(title:Text("Giriş")), body: 
      IconButton(icon:Icon(Icons.signal_cellular_4_bar),onPressed: logout)
    );
  }
}

我想做的是将我的用户数据保存到firebase并显示加载屏幕。它有效,但是函数中的print语句不断被无限次调用。我知道它与setState有关,但我不明白为什么它会不断渲染和调用该函数。如果有人能告诉我为什么我继续在控制台中获取打印的用户ID,我将感到非常高兴。

1 个答案:

答案 0 :(得分:3)

您当前正在使用getGoogleContent方法调用build。调用setState会触发新的重建。由于您实际上是通过在setState中调用build来在getGoogleContent中调用build,所以创建了一个无限循环。

要解决此问题,请将getGoogleContent(auth);移至initState,以便仅调用一次,并且重建不会再次触发此方法:

@override
void initState() {
  super.initState();
  getGoogleContent(auth);
}

虽然当前的在加载数据时显示加载屏幕的方法是有效的,但是FutureBuilder消除了当前方法的许多复杂性,并防止了此类错误的发生。