我想知道什么时候使用FutureBuilder,以及它是如何有用的,因为一个小部件可以在其生命周期内多次构建,而不仅仅是当我们使用setState或更新它时,所以不要使用下面的代码:
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将是更有用和正确的比上述设置。
发布于 2021-08-28 21:56:28
FutureBuilder用于处理返回要显示的数据的“异步”调用。
例如,假设我们必须从服务器获得一个List<String>。
API调用:
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 )
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 bool和String for error...etc的状态类。FutureBuilder为我们节省了时间。
但
因为FutureBuilder是一个小部件,并且存在于小部件树中,所以重新构建可以使FutureBuilder再次运行。
因此,我想说,当您知道不会进行重建时,可以使用FutureBuilder,但是有许多方法(在互联网中)可以防止在重建发生时再次调用FutureBuilder,但它对我无效,并导致意外的行为。
老实说,与使用FutureBuilder相比,我更喜欢在不同的类中使用状态管理解决方案来处理状态,因为它会更安全(重新构建不会影响它)、更有用和更容易阅读(从UI中扩展业务逻辑)。
发布于 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
发布于 2021-08-28 17:18:29
实际上,如果您不想使用FutureBuilder Widget,您将永远不需要使用它。如果您对FutureBuilder Widget进行了正确的优化,那么代码中的逻辑将与FutureBuilder Widget完全相同。
此代码与您的代码完全相同:
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),
),
);
}
}
);
}
}https://stackoverflow.com/questions/68372366
复制相似问题