Navigator.pop 来自 FutureBuilder

Navigator.pop from a FutureBuilder

我有一个要求用户输入的第一个屏幕,然后当用户单击一个按钮时,应用程序进入第二个屏幕,该屏幕使用 FutureBuilder 调用 API。

如果 API returns 出错,我想用 Navigator.pop 返回到上一个屏幕。当我尝试在 FutureBuilder 的构建器中执行此操作时,出现错误,因为我在构建树时修改了树...

setState() or markNeedsBuild() called during build. This Overlay widget cannot be marked as needing to build because the framework is already in the process of building widgets

如果发生错误,返回上一屏幕的正确方法是什么?

class Whosebug 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,但是不知为何,被调用了多次

构建方法为 运行 时无法直接导航,因此最好显示一些错误屏幕并让用户有机会返回上一屏幕。

但是如果你想这样做,那么你可以使用下面的语句来做到这一点。

Future.microtask(() => Navigator.pop(context));

我更愿意将 class 转换为 StateFullWidget 并删除 FutureBuilder

class Whosebug extends StatefulWidget {

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

class _WhosebugState extends State<Whosebug> {
  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 class 不是好的方法