首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >何时在颤振中使用FutureBuilder

何时在颤振中使用FutureBuilder
EN

Stack Overflow用户
提问于 2021-07-14 05:12:54
回答 6查看 4.3K关注 0票数 6

我想知道什么时候使用FutureBuilder,以及它是如何有用的,因为一个小部件可以在其生命周期内多次构建,而不仅仅是当我们使用setState或更新它时,所以不要使用下面的代码:

代码语言:javascript
运行
复制
class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool done = false;

  @override
  void initState() {
    wait();
    super.initState();
  }

  Future<void> wait() async {
    await Future.delayed(Duration(seconds: 2));
    setState(() {
      done = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    print('is built');
    return done ? Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    ) : Scaffold(body: CircularProgressIndicator(),);
  }
}

在这种情况下,FutureBuilder可以代替上面的设置,因为我也希望优化我的应用程序,以减少后端读取(在FutureBuilder中,我会多读一次)。我正在寻找的情况下,FutureBuilder将是更有用和正确的比上述设置。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2021-08-28 21:56:28

FutureBuilder用于处理返回要显示的数据的“异步”调用。

例如,假设我们必须从服务器获得一个List<String>

API调用:

代码语言:javascript
运行
复制
  Future<List<String>> getStringList() async {
    try {
      return Future.delayed(Duration(seconds: 1)).then(
        (value) => ['data1', 'data2', 'data3', 'data4'],
      );
    } catch (e) {
      throw Exception(e);
    }
  }

如何使用error...etc处理上述API调用状态(加载、数据、FutureBuilder )

代码语言:javascript
运行
复制
FutureBuilder<List<String>?>(
        future: getStringList(),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              return Center(
                child: CircularProgressIndicator(),
              );
            case ConnectionState.done:
              if (snapshot.hasError)
                return Text(snapshot.error.toString());
              else
                return ListView(
                  children: snapshot.data!.map((e) => Text(e)).toList(),
                );

            default:
              return Text('Unhandle State');
          }
        },
      ),

正如我们所看到的,我们不必创建一个带有变量isLoading boolString for error...etc的状态类。FutureBuilder为我们节省了时间。

因为FutureBuilder是一个小部件,并且存在于小部件树中,所以重新构建可以使FutureBuilder再次运行。

因此,我想说,当您知道不会进行重建时,可以使用FutureBuilder,但是有许多方法(在互联网中)可以防止在重建发生时再次调用FutureBuilder,但它对我无效,并导致意外的行为。

老实说,与使用FutureBuilder相比,我更喜欢在不同的类中使用状态管理解决方案来处理状态,因为它会更安全(重新构建不会影响它)、更有用和更容易阅读(从UI中扩展业务逻辑)。

票数 8
EN

Stack Overflow用户

发布于 2021-07-14 07:08:46

FutureBuilder

基于与未来交互的最新快照构建自己的小部件。

未来必须是提前获得的,例如在State.initState、State.didUpdateWidget或State.didChangeDependencies期间。在构造State.build或StatelessWidget.build方法时,不能在FutureBuilder方法调用期间创建FutureBuilder。

如果将来与FutureBuilder同时创建,那么每次重建FutureBuilder的父任务时,异步任务都会被重新启动。一般准则是假设每个构建方法都可以调用每个框架,并将省略的调用视为优化。

文档是一种非常好的方法,可以开始并了解小部件在什么情况下做什么.

https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

票数 2
EN

Stack Overflow用户

发布于 2021-08-28 17:18:29

实际上,如果您不想使用FutureBuilder Widget,您将永远不需要使用它。如果您对FutureBuilder Widget进行了正确的优化,那么代码中的逻辑将与FutureBuilder Widget完全相同。

此代码与您的代码完全相同:

代码语言:javascript
运行
复制
class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool done = false;
  late Future myFuture;

  @override
  void initState() {
    myFuture = wait();
    super.initState();
  }

  Future<bool> wait() async {
    await Future.delayed(const Duration(seconds: 2));
    return true;
  }

  @override
  Widget build(BuildContext context) {
    print('is built');
    return FutureBuilder(
        future: myFuture,
        builder: (BuildContext context, snapshot) {
           if(snapshot.connectionState == ConnectionState.waiting) {
              return const Scaffold(body: CircularProgressIndicator(),);
           } else {
              return Scaffold(
                 body: Center(
                    child: Column(
                       mainAxisAlignment: MainAxisAlignment.center,
                       children: <Widget>[
                          const Text(
                             'You have pushed the button this many times:',
                          ),
                          Text(
                              '',
                              style: Theme.of(context).textTheme.headline4,
                          ),
                       ],
                     ),
                   ),
                floatingActionButton: FloatingActionButton(
                   onPressed: () {},
                   tooltip: 'Increment',
                   child: const Icon(Icons.add),
                ),
             );
           }
        }
     );
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68372366

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档