InitState вызывается несколько раз

В моем приложении у меня есть экран входа в систему и домашний экран. При переходе от логина к главному экрану я читаю данные из файла .txt и показываю 4 случайных точки данных. Я получаю данные из файла в своем initState, чтобы он не вызывался несколько раз при изменении состояния, а затем ждал его с помощью будущего построителя, например...

class _HomeScreenState extends State<HomeScreen> {
  Future<bool> _future;

  @override
  initState() {
    super.initState();
    print('in initState about to call _getData');
    _future = _getData();
  }

  @override
  Widget build(BuildContext context) {
    var futureBuilder = new FutureBuilder(
      future: _future,
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.none:
          case ConnectionState.active:
          case ConnectionState.waiting:
            return new Center(
              child: new CircularProgressIndicator(),
            );
          case ConnectionState.done:
            if (snapshot.hasError) {
              return new Center(
                child: Text('Error'),
              );
            } else {
              return new ListView(
                children: <Widget>[
                  //my view
                ],
              );
            }
          }
        }
    );
    return MaterialApp(
        home: WillPopScope(
          onWillPop: () async {
            return Navigator.pop(context);
          },
          child: Scaffold(
            body: futureBuilder,
          ),
        )
    );

Теперь, когда я возвращаюсь к экрану входа в систему с помощью кнопки «Назад», а затем возвращаюсь к домашнему экрану, initState будет отключаться несколько раз (это можно увидеть по оператору печати, который я оставил). По мере того, как вы переключаетесь между этими двумя экранами (открываете домашний экран, нажимаете домашний экран), initState будет вызываться экспоненциально большее количество раз. Я так запутался, любая помощь приветствуется!

Обновлено: Полный код для входа и домашнего экрана можно найти https://github.com/ViscousOx/Флаттер-материал

Можете ли вы показать полный виджет (также класс с сохранением состояния) + его потенциальный родитель?

Rémi Rousselet 23.01.2019 03:02

@RémiRousselet Я загрузил оба виджета на github по адресу github.com/ViscousOx/Флаттер-материал.

JJ Stamp 23.01.2019 03:30

Вы нашли ответ на это? Я тоже сталкиваюсь с тем же, я использую пакет provider.

PeakGen 03.03.2020 13:04

@RémiRousselet: я использую пакет provider и испытываю то же самое.

PeakGen 03.03.2020 13:04
1
4
1 567
2

Ответы 2

Попробуйте это: это работает Используйте оператор по умолчанию с ConnectionState.waiting.

class _HomeScreenState extends State<HomeScreen> {
  Future<bool> _future;

  @override
  initState() {
    super.initState();
    print('in initState about to call _getData');
    _future = _getData();
  }

  @override
  Widget build(BuildContext context) {
    var futureBuilder = new FutureBuilder(
      future: _future,
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.waiting:
            return new Center(
              child: new CircularProgressIndicator(),
            );
          default:
            if (snapshot.hasError) {
              return new Center(
                child: Text('Error'),
              );
            } else {
              return new ListView(
                children: <Widget>[
                  //my view
                ],
              );
            }
          }
        }
    );
    return MaterialApp(
        home: WillPopScope(
          onWillPop: () async {
            return Navigator.pop(context);
          },
          child: Scaffold(
            body: futureBuilder,
          ),
        )
    );

Можно избежать состояния ожидания соединения. Я использовал как:

FutureBuilder(future: _isUserLoggedIn(),
                     builder: (ctx, loginSnapshot) => 
                      loginSnapshot.data == true ?  AppLandingScreen() : SignUpScreen()
                ),

Другие вопросы по теме