【问题标题】:Correct way of using FutureBuilderFutureBuilder的正确使用方法
【发布时间】:2021-09-17 05:29:45
【问题描述】:

所以我有一些关于如何正确使用 FutureBuilder 的问题。我在某处读到我们应该将未来存储在一个变量中,并在 FutureBuilder 而不是未来服务中调用该变量。但是我们如何初始化那个变量的初始值呢?当我厌倦了这个时,它总是给LateInitializationError: Field '_dataFuture@28307501' has not been initialized.,应该等到数据加载完毕。

  late Future<List<TransaksiResp>> _dataFuture;

  @override
  void initState() {
    super.initState();
    transaksiService = TransaksiService();
    getUserPrefs().then((value) {
      setState(() {
        _dataFuture = transaksiService.getTransaksi(user[2]);});
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(

      body: Column(
        children: <Widget>[
          Flexible(
            child: SizedBox(
              child: FutureBuilder<List<TransaksiResp>>(
                future: _dataFuture,
                builder: (BuildContext context, AsyncSnapshot snapshot) {
                  if(snapshot.hasError) {
                    print(snapshot);
                    return Center(
                      child: Text("Error"),
                    );
                  } else if (snapshot.hasData){
                    List<TransaksiResp> response = snapshot.data;
                    return _buildListView(response);
                  } else {
                    return Center(
                      child: Container(),
                    );
                  }
                },
              ),
            ),
          )
        ],
      ),
    );
  }

这是从共享首选项中获取用户数据的 getUserPrefs 方法

 Future<void> getUserPrefs() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    user = prefs.getStringList("user")!;
    setState(() {});
  }

【问题讨论】:

  • 你应该在initState中使用_dataFuture = someMethodReturningYourFuture();
  • 已经在initState中,在调用getUserPrefs之后,还是直接在initState?里面调用因为我需要来自getUserPrefs的数据来调用服务
  • 不,您在 .then 内部分配 _dataFuture = ... 在调用 build 方法后调用的回调 - 检查它在 build() 方法中添加一个 print('build') 和另一个 print('then')内部.then回调
  • 基本上你应该使用_dataFuture = someMethodReturningYourFuture();而不使用任何setState等,只需编写一个返回Futureasync方法,更多阅读Asynchronous programming: futures, async, await

标签: flutter


【解决方案1】:

得到答案,因为我需要SharedPreferences的数据,所以需要先等待函数完成

  _getService() async {
    await getUserPrefs();
    return await transaksiService.getTransaksi(user[2]);
  }

然后在iniState中调用它并保存在一个变量中

 _dataFuture = _getService();

【讨论】:

  • 顺便说一句,你可以直接调用return transaksiService.getTransaksi(user[2]); - 这里不需要await,我也会从getUserPrefs返回用户数据,这样你就可以避免全局user变量/字段:final user = await getUserPrefs();
【解决方案2】:
  • FutureBuilder 删除样板代码。

  • FutureBuilder 小部件用于根据与 Future 交互的最新快照创建小部件。未来有必要 通过改变状态或改变依赖关系更早地获得。

如果您从 API 获取数据,请参考我的回答 hereherehere 希望在我使用 FutureBuilder 的示例中对您有所帮助。

请参阅文档 here 了解 FutureBuilder

您也可以参考here

希望对你有所帮助

【讨论】:

  • 我之前用过这个方法,也有人说要保存到变量中,而不是直接调用服务
  • 您的确切问题是什么我的意思是您将数据发送到JSON API
  • tbh,它没有问题。我只是想知道如何正确使用 FutureBuilder
  • 参考this视频
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-19
  • 2015-12-17
  • 2012-02-23
  • 2013-01-09
  • 2010-12-28
  • 2012-04-26
  • 2014-10-24
相关资源
最近更新 更多