Flutter setState вызывается несколько раз в провайдере - PullRequest
0 голосов
/ 15 апреля 2020

Во-первых, мой Engli sh явно не совершенен: я сделаю все возможное! Я совсем новичок с Флаттером. Основная идея - вывести пользователей моего приложения на хороший экран в зависимости от его роли. Все пользователи хранятся в базе данных FireStore. Моя проблема в том, что функция setState, кажется, вызывается несколько раз. Если пользователь не равен NULL, я хочу прочитать поле «роль» пользователя в базе данных, а затем, в зависимости от его роли, я хочу, чтобы он был перенаправлен на страницу администратора или на страницу клиента. Чтобы возобновить, я просто хочу один раз прочитать роль, а затем перенаправить. Но, как я уже говорил, если я помещаю отпечаток в setState, он вызывается несколько раз ... Что я могу сделать, чтобы это исправить?

Спасибо!

  @override
  Widget build(BuildContext context) {
    User user= Provider.of<User>(context);
    final AuthService _auth=AuthService();

    if(user ==null){
      return SignIn();
    } else{
      getRoleWrapper(user).then((s) {
        setState(() {
          user.setRole(s);
        });
      });

      if(user.role=="administrateur"){
        return PageTestAdmin();
      }else{
        return BasicClient();
      }
    }
  }
}

Future<String> getRoleWrapper (User user) async{
  final AuthService _auth=AuthService();
  String role=await _auth.getRole(user);
  return role;
} 



1 Ответ

0 голосов
/ 15 апреля 2020

То, что вы хотите сделать, это добавить перенаправление внутри кода .then, чтобы оно запускалось сразу после завершения setRole. Вам не нужен setState внутри, потому что он бесполезен. Причина, по которой setState запускается несколько раз, заключается в том, что при каждом вызове setState функция Widget build (...) запускается снова, поэтому вы вводите бесконечное значение l oop. Выньте setState и перенаправьте, как только роль будет определена. Я думаю, что это решит вашу проблему. Код вам нужен ниже. Пожалуйста, проголосуйте и примите это как ответ (щелкните галочкой), если это решит вашу проблему.

Еще одна точка исправления. Скорее всего, вам придется инициализировать вашу пользовательскую переменную и переменную _auth вне функции сборки. В Dart / Flutter после setState вся сборка запускается снова, и поэтому эти переменные нельзя использовать вне функции сборки. Попробуйте инициализировать эти переменные внутри функции @override initState (...).

User user;
AuthService _auth;
bool isLoaded = false;

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

  user = Provider.of<User>(context);
  AuthService _auth = AuthService();

}

@override
Widget build(BuildContext context) {

  if (!isLoaded) {

    if(user == null){

      return SignIn();

    }
    else {

      getRoleWrapper(user, _auth).then((s) {

        user.setRole(s);

        setState(() {
          isLoaded = true;
        });


      });


    }

  }

  return isLoaded ?
  user.role == "administrateur" ?
  PageTestAdmin() : BasicClient()
  :
  Container();

}

Future<String> getRoleWrapper (User user, AuthService auth) async{

  String role = await auth.getRole(user);
  return role;
}
...