【问题标题】:Flutter - Wait setState in FutureBuilder then load componentFlutter - 在 FutureBuilder 中等待 setState 然后加载组件
【发布时间】:2020-03-22 01:32:31
【问题描述】:

我正在尝试类似的方法。在 Future Builder 中加载服务,设置 Text Field 值,然后编写组件。

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

但是返回

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

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

【问题讨论】:

    标签: flutter


    【解决方案1】:

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

    事实上,您不应该在 build.xml 中执行任何业务逻辑。从您的代码中,您似乎想在页面出现时加载一些数据并将一些初始字段设置为您的TextFields。我认为您不想在这里使用FutureBuilder,因为您有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
        );
      }
    }
    

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

    【讨论】:

    • 自从 FutureBuilder 和 StreamBuilder 不适合我以来我一直在寻找的方法
    【解决方案2】:

    基本上,您需要了解 FutureBuilder 以这种方式调用的内容。 FutureBuilder 有一个子 future:,您为其分配了一个异步方法,该方法附加了 .then。 '.then' 将在异步过程完成后被调用。

    得到答案,你可以这样调用 setState。

    myFutureMethod.then((value) => {
          setState(() {
            value = true;
          })
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-28
      • 2020-09-02
      • 2020-04-14
      • 2021-11-30
      • 2021-02-10
      • 2021-08-15
      • 2021-09-06
      • 1970-01-01
      相关资源
      最近更新 更多