flutter 抛出异常:在生成期间调用了setState()或NeedmarksBuild()

vuktfyat  于 2023-02-09  发布在  Flutter
关注(0)|答案(1)|浏览(117)

我对这个exception was thrown: setState() or markNeedsBuild() called during build.有点困惑,我知道这个WidgetsBinding.instance.addPostFrameCallback((timeStamp) {});代码行可以解决这个问题,但是我想知道为什么会发生这个问题,为什么我们要使用这个addPostFrameCallback。我想知道这个异常的深层概念和意义,因为这个异常有时候让我很生气,我的代码运行得很好,但它突然出现了。我不知道更深的层次,但我认为它与我们的状态有关,我认为我们的状态没有正确构建,状态被再次调用,它会产生循环。这就是为什么flutter抛出此异常。
我注意到,当我是新手的flutter,我把这个setState()内的build方法,所以这个异常出现了。我得到的想法,这使循环的状态,所有我们知道setState()是用于重建状态和调用build方法的小部件树,这重建我们的小部件与动态值.
如果我对这个例外有误解,我希望任何人都能澄清。
我将附加下面的代码,当第二次进入屏幕时,将产生异常:

class UpcomingAppointmentsScreen extends StatelessWidget {
  UpcomingAppointmentsScreen({Key? key}) : super(key: key);

  AppointmentController controller = Get.find();

  @override
  Widget build(BuildContext context) {
    controller.getupcomingAppointments(); //At this line exception comes up.

    return Scaffold(
      backgroundColor: MColors.colorBackgroundLight,
      body: Stack(
        children: [
          Obx(() {
            if (controller.upcomingAppointments.isEmpty &&
                !(controller.upcomingAppoinmentLoadingState.value)) {
              return Center(
                child: Text(
                  'No upcoming appointments found',
                  style: TextStyle(
                      color: Colors.black,
                      fontSize: FontSize.largeTextSize,
                      fontWeight: FontWeight.bold),
                ),
              );
            } else {
              return ListView.builder(
                  padding: const EdgeInsets.all(3),
                  itemCount: controller.upcomingAppointments.length,
                  itemBuilder: (context, index) {
                    var appointment = controller.upcomingAppointments[index];
                    return AppointmentCard(appointment);
                  });
            }
          }),
          Obx(() {
            return Visibility(
                visible: controller.upcomingAppoinmentLoadingState.value,
                child: Center(child: CircularProgressIndicator()));
          })
        ],
      ),
    );
  }
}

API调用并将数据设置为模型列表:

getupcomingAppointments() {
    upcomingAppoinmentLoadingState.value = true;
    ApiCalls.appointmentsHistory().then((value) {
     
      List list = value['Upcoming Appointments'];
      upcomingAppointments.clear();
      list.forEach((element) {
        upcomingAppointments.add(AppointmentsData.fromJson(element));
      });

      upcomingAppoinmentLoadingState.value = false;
    }).catchError((onError) {
      upcomingAppoinmentLoadingState.value = false;
    });
  }
tgabmvqs

tgabmvqs1#

回调在持久帧回调之后执行,或者在当前帧(如果正在进行)期间执行,或者在下一帧期间执行。回调的执行顺序由它们的添加顺序确定,并且一旦添加就不能取消注册

因此,您的构建方法被直接调用,addPostFrameCallback等待,直到数据不来,然后调用构建方法。它将持有方法的一段时间。

相关问题