Flutter Flatter FutureProvider执行构建两次

Flutter Flatter FutureProvider执行构建两次,flutter,Flutter,我已经从使用initState获取数据和Futurebuilder将其加载到Futureprovider的Statefulwidget进行了更改。但似乎Futureprovider是两次执行build方法,而我以前的方法只执行了一次。这种行为正常吗 class ReportsPage extends StatelessWidget { const ReportsPage({Key key}) : super(key: key); @override Widget build(Bui

我已经从使用
initState
获取数据和
Futurebuilder
将其加载到
Futureprovider
Statefulwidget
进行了更改。但似乎
Futureprovider
是两次执行
build
方法,而我以前的方法只执行了一次。这种行为正常吗

class ReportsPage extends StatelessWidget {
  const ReportsPage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return FutureProvider<List<ReportModel>>(
      create: (_) async => ReportsProvider().loadReportData(1),
      initialData: null,
      catchError: (_, __) => null,
      child: const ReportWidg()
    );
  }
}

class ReportWidg extends StatelessWidget {
  const ReportWidg();

  @override
  Widget build(BuildContext context) {
    print("Execute Build");
    final reportList = Provider.of<List<ReportModel>>(context);
    if (reportList == null) {
      return Center(child: CircularProgressIndicator());
    } else if (reportList.isEmpty) {
      return Center(child: Text("Det finns inga rapporter."));
    }

    print(reportList.length);
    return Container();
  }
}
class ReportsPage扩展了无状态小部件{
const ReportsPage({Key}):super(Key:Key);
@凌驾
小部件构建(构建上下文){
返回未来提供者(
创建:(41; async=>ReportsProvider().loadReportData(1),
initialData:null,
catchError:(u,u)=>null,
子项:const ReportWidg()
);
}
}
类ReportWidg扩展了无状态小部件{
const ReportWidg();
@凌驾
小部件构建(构建上下文){
打印(“执行构建”);
最终报告列表=提供者(上下文);
if(reportList==null){
返回中心(子项:CircularProgressIndicator());
}else if(reportList.isEmpty){
返回中心(儿童:文本(“Det finns inga Reporter”);
}
打印(reportList.length);
返回容器();
}
}

我对flift相对来说是个新手,但我认为这是因为
无状态小部件
@不可变的
,这意味着无论什么时候发生变化,它都需要重建自身

在第一次构建时,进行了
async
调用,并呈现了
ReportWidg()

然后这一行
final reportList=Provider.of(context)获取新获取的数据作为
异步
函数的结果,因此
不可变
小部件需要重建自身,因为它不能“更改”

在面向对象和函数式编程中,一种不可变的对象 (不可更改对象)是其状态无法修改的对象 在它被创建之后。。。这与可变对象形成对比 (可更改对象),创建后可对其进行修改


还是我错了?

我对颤振相对来说是个新手,但我认为这是因为
无状态widget
@不可变的
,这意味着无论什么时候发生变化,它都需要重建自身

在第一次构建时,进行了
async
调用,并呈现了
ReportWidg()

然后这一行
final reportList=Provider.of(context)获取新获取的数据作为
异步
函数的结果,因此
不可变
小部件需要重建自身,因为它不能“更改”

在面向对象和函数式编程中,一种不可变的对象 (不可更改对象)是其状态无法修改的对象 在它被创建之后。。。这与可变对象形成对比 (可更改对象),创建后可对其进行修改


还是我错了?

我怀疑您的FutureProvider应该被提升到一个单一的实例化中,就像放在任何build()方法之外的全局变量中一样。这当然会缓存结果,因此您可以通过让值依赖于正在监视的其他提供程序()或通过FutureProvider.family将其设置为重新生成。

我怀疑您的FutureProvider应该被提升到单个实例化中,就像放在任何build()方法之外的全局变量中一样。这当然会缓存结果,因此您可以通过让值依赖于正在监视的其他提供程序()或通过FutureProvider.family将其设置为重新生成。

在您的情况下,您应该使用
消费者
,即

FutureProvider。。。,

儿童:消费者在您的情况下,您应该使用
消费者
,即

FutureProvider。。。,

子:消费者您可以复制粘贴运行下面的完整代码
对这是正常的
第一次
执行Build
报告列表
null
并显示
CircularProgressIndicator()

第二次
执行构建
报告列表
有数据并显示数据

如果设置了
listen:false
final reportList=Provider.of(上下文,listen:false)
您只会得到一个
executebuild
,屏幕将始终显示
circularproressindicator()

在工作演示中,模拟5秒的网络延迟,这样您就可以看到
循环ProgressIndicator()
,然后显示
列表视图

您可以参考
代码片段

Widget build(BuildContext context) {
    print("Execute Build");
    final reportList = Provider.of<List<ReportModel>>(context);
    print("reportList ${reportList.toString()}");
    if (reportList == null) {
      print("reportList is null");
      return Center(child: CircularProgressIndicator());
    } else if (reportList.isEmpty) {
      return Center(child: Text("Empty"));
    }

    return Scaffold(
      body: ListView.builder(
          itemCount: reportList.length,
小部件构建(构建上下文){
打印(“执行构建”);
最终报告列表=提供者(上下文);
打印(“reportList${reportList.toString()}”);
if(reportList==null){
打印(“报告列表为空”);
返回中心(子项:CircularProgressIndicator());
}else if(reportList.isEmpty){
返回中心(子项:文本(“空”);
}
返回脚手架(
正文:ListView.builder(
itemCount:reportList.length,
工作演示

完整代码

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class ReportModel {
  String title;

  ReportModel({this.title});
}

class ReportsProvider with ChangeNotifier {
  Future<List<ReportModel>> loadReportData(int no) async {
    await Future.delayed(Duration(seconds: 5), () {});
    return Future.value([
      ReportModel(title: "1"),
      ReportModel(title: "2"),
      ReportModel(title: "3")
    ]);
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ReportsPage(),
    );
  }
}

class ReportsPage extends StatelessWidget {
  const ReportsPage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return FutureProvider<List<ReportModel>>(
        create: (_) async => ReportsProvider().loadReportData(1),
        initialData: null,
        catchError: (_, __) => null,
        child: const ReportWidg());
  }
}

class ReportWidg extends StatelessWidget {
  const ReportWidg();

  @override
  Widget build(BuildContext context) {
    print("Execute Build");
    final reportList = Provider.of<List<ReportModel>>(context);
    print("reportList ${reportList.toString()}");
    if (reportList == null) {
      print("reportList is null");
      return Center(child: CircularProgressIndicator());
    } else if (reportList.isEmpty) {
      return Center(child: Text("Empty"));
    }

    return Scaffold(
      body: ListView.builder(
          itemCount: reportList.length,
          itemBuilder: (context, index) {
            return Card(
                elevation: 6.0,
                child: Padding(
                  padding: const EdgeInsets.only(
                      top: 6.0, bottom: 6.0, left: 8.0, right: 8.0),
                  child: Text(reportList[index].title.toString()),
                ));
          }),
    );
  }
}
导入“包装:颤振/材料.省道”;
导入“包:provider/provider.dart”;
类报告模型{
字符串标题;
ReportModel({this.title});
}
带有ChangeNotifier的类ReportsProvider{
未来loadReportData(int no)异步{
等待未来。延迟(持续时间(秒:5),({});
返回未来值([
报告模型(标题:“1”),
报告模型(标题:“2”),
报告模型(标题:“3”)
]);
}
}
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
主页:ReportsPage(),
);
}
}
类ReportsPage扩展了无状态小部件{
const ReportsPage({Key}):super(Key:Key);
@凌驾
小部件构建(构建上下文){
返回未来提供者(
创建:(41; async=>ReportsProvider().loadReportData(1),
initialData:null,
catchError:(u,u)=>null,
child:const ReportWidg());
}
}
类ReportWidg扩展了无状态小部件{
const ReportWidg();