Flutter - 在 FutureBuilder 中等待 setState 然后加载组件

El *_*bre 0 flutter

我\xc2\xb4m尝试类似的事情。在 Future Builder 中加载服务,设置文本字段值,然后编写组件。

\n\n
 final data = FutureBuilder(\n            future: DatameterService.getMapData(),\n            builder: (context, snapshot) {\n              if (snapshot.connectionState == ConnectionState.done) {\n                setState(() {\n                  calleController.text = snapshot.data.calle;\n                  paisController.text = snapshot.data.pais;\n                  provinciaController.text = snapshot.data.provincia;\n                  poblacionController.text = snapshot.data.poblacion;\n                  postalController.text = snapshot.data.postal;\n                });\n                return form;\n              } else {\n                return indicator;\n              }\n
Run Code Online (Sandbox Code Playgroud)\n\n

但返回

\n\n
\n

在构建期间调用 setState() 或 markNeedsBuild()。

\n
\n\n

所以问题是:如何使用 FutureBuilder 填充 TextField 输入值?

\n

小智 6

你永远不应该打电话setState,原因很简单:setState 导致构建,而构建调用 setState - 你处于无限循环中。这就是为什么引擎明确告诉您不应该尝试这样做。

事实上,您不应该在构建中执行任何业务逻辑。从您的代码来看,您似乎想在页面出现时加载一些数据,并为您的TextFields 设置一些初始字段。我认为你不想FutureBuilder在这里使用 a ,因为你有一个StatefulWidget. 相反,您可以将 future 移出构建并调用它initState

像这样的东西:

class _MyState extends State<MyWidget> {
  Map<String, dynamic> _data;
  bool _loading;
  TextEditingController _controller;

  @override
  void initState() {
    super.initState();
    // start fetching
    _loading = true;
    _data = {};
    _controller = TextEditingController();
    getData().then((data) {
      setState(() {
        _data = data;
        _loading = false;
        _controller.text = _data['text'];
      });
    });
  }

  Widget build(BuildContext context) {
    // handle loading vs. not loading
    if (_loading) return CircularProgressIndicator();
    return Container(
      // the rest of your code
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

您实际上甚至不需要存储_data,但它对于重置表单或其他内容可能很有用。