Navigator.pop от FutureBuilder - PullRequest
       53

Navigator.pop от FutureBuilder

0 голосов
/ 30 марта 2020

У меня есть первый экран, который просит пользователя ввести данные для ввода, затем, когда пользователи нажимают на кнопку, приложение переходит на второй экран, который использует FutureBuilder для вызова API.

Если API возвращает ошибку, я бы хотел go вернуться на предыдущий экран с Navigator.pop. Когда я пытаюсь сделать это в конструкторе FutureBuilder, я получаю сообщение об ошибке, потому что я изменяю дерево во время его построения ...

setState () или markNeedsBuild (), вызываемые во время сборки. Этот виджет наложения не может быть помечен как необходимый для сборки, потому что каркас уже находится в процессе создания виджетов

Как правильно go перейти к предыдущему экрану в случае возникновения ошибки?

class Stackoverflow extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: FutureBuilder<Flight>(
            future: fetchData(context),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ScreenBody(snapshot.data);
              } else if (snapshot.hasError) {
                Navigator.pop(context, "an error");
              }
              // By default, show a loading spinner.
              return CircularProgressIndicator();
            },
          )
      ),
    );
  }
}

PS: я пытался использовать addPostFrameCallback и использовать Navigator.pop внутри, но по неизвестной причине он вызывается несколько раз

Ответы [ 2 ]

1 голос
/ 30 марта 2020

Я бы предпочел преобразовать класс в StateFullWidget и избавиться от FutureBuilder

class Stackoverflow extends StatefulWidget {

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

class _StackoverflowState extends State<Stackoverflow> {
  Flight flight;

  @override
  void initState() {
    super.initState();
    fetchData().then((data) {
      setState(() {
        flight = data;
      });
    }).catchError((e) {
      Navigator.pop(context, "an error");
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: flight != null ? ScreenBody(flight) : CircularProgressIndicator(),
      ),
    );
  }
}

и передачи причины context где-то за пределами класса - не очень хороший подход

1 голос
/ 30 марта 2020

Вы не можете напрямую перемещаться, когда работает метод сборки, поэтому лучше показать экран ошибок и дать возможность использовать go для возврата к последнему экрану.

Однако, если вы хотите сделать это, то вы для этого можно использовать следующее утверждение.

Future.microtask(() => Navigator.pop(context));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...