flutter 防止从子部件重建FutureBuilder

eqzww0vc  于 2023-06-30  发布在  Flutter
关注(0)|答案(1)|浏览(261)

为了显示从firestore加载数据,我创建了这个小部件:

class GetDeploymentDetails extends StatelessWidget {
  const GetDeploymentDetails({required this.user, super.key});
  final User? user;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<Deployment>(
      future: FirebaseFirestore.instance
          .collection('deployments')
          .where("users", arrayContains: user!.email)
          .get()
          .then((value) => Deployment.fromJson(value.docs[0].data())),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Scaffold(
            body: const Center(
              child: CircularProgressIndicator(),
            ),
          );
        } else if (!snapshot.hasData) {
          return Scaffold(
            body: const Center(
              child: Text('No deployments found, please contact admin.'),
            ),
          );
        } else
          return AppHomeScreen(
            user: user,
            deployment: snapshot.data!,
          );
      },
    );
  }
}

但是每次我在AppHomeScreen中进行需要重建的UI更改时,整个UI都会重新加载并将我带回到第一页。例如,点击文本字段以输入一些文本,再次调用AppHomeScreen的构建方法并重新加载整个应用程序的数据。
我该怎么解决这个问题?什么是正确的方式来调用期货和流之间的小部件加载,同时能够显示数据加载与循环进度指标。

yqhsw0fo

yqhsw0fo1#

正如@Randal Schwartz在他分享的评论和视频中提到的那样,不要在构建Widget中构建Stream或Future Builder,因为每次状态更改时都会重新构建。
相反,您应该考虑将构造的Future移动到类示例变量,如下所示:

class GetDeploymentDetails extends StatelessWidget {
  const GetDeploymentDetails({required this.user, super.key});
  final User? user;
final constructed_future = FirebaseFirestore.instance
          .collection('deployments')
          .where("users", arrayContains: user!.email)
          .get()
          .then((value) => Deployment.fromJson(value.docs[0].data()));

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<Deployment>(
      future: constructed_future,
      builder: (context, snapshot) {
// … other stuff
}

参考文献:

相关问题