如何解决“未经手”的例外:setState()或markneedsbuild()在构建过程中调用?

发布于 2025-01-31 11:26:25 字数 14510 浏览 2 评论 0原文

在这里,我使用OBX显示一个OBS变量,首先没有显示错误,但是当我进行热重新启动时,它显示了此错误。

未经手的异常:setState()或MarkneedSbuild()在构建过程中调用。 这个OBX小部件不能被标记为需要构建,因为该框架已经在构建小部件的过程中。仅当其祖先之一目前正在建造时,才能将小部件标记为需要在构建阶段建造。允许使用此例外,因为该框架在孩子们面前建立了父母小部件,这意味着将始终建造一个肮脏的后代。否则,该框架可能不会在此构建阶段访问此小部件。 setState()或MarkneedSbuild()的小部件是: OBX

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

  @override
  Widget build(BuildContext context) {
    var detailHotelController = Get.put(DetailHotelController());
    var homeController = Get.put(HomeController());
    var userDataFormController = Get.put(UserDataFormController());
    var checkoutController = Get.put(CheckoutController());
    var bookingController = Get.put(BookingController());
    var authController = Get.put(AuthController());
    final orientation = MediaQuery.of(context).orientation;
    detailHotelController.getDetailHotel(userDataFormController.hotelId.value);
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        toolbarHeight: 20.w,
        title: Image.asset(
          "assets/turu.png",
          height: 10.h,
        ),
        elevation: 0,
        backgroundColor: Colors.white10,
      ),
      body: Padding(
        padding: const EdgeInsets.only(bottom: 16.0),
        child: SingleChildScrollView(
          child: Obx(
            () => (detailHotelController.isLoading.value)
                ? Center(
                    child: LoadingAnimationWidget.waveDots(
                        color: const Color(0xffF0B900), size: 50))
                : Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            "Tinjau Pemesanan",
                            style: TextStyle(
                                fontSize: 14.sp,
                                color: const Color(0xffF0B900),
                                fontWeight: FontWeight.bold),
                          ),
                          Padding(
                            padding: const EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 1.sp,
                            ),
                          ),
                          Text(
                            detailHotelController.detailHotel.value.hotel!.name,
                            style: TextStyle(
                                fontSize: 13.sp, fontWeight: FontWeight.bold),
                          ),
                          const SizedBox(
                            height: 12,
                          ),
                          Text(
                            detailHotelController
                                .detailHotel.value.hotel!.address
                                .replaceAll("\n", " "),
                            style: TextStyle(fontSize: 10.sp),
                          ),
                          const Padding(
                            padding: EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 2,
                            ),
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            mainAxisSize: MainAxisSize.max,
                            children: [
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text(
                                    "Check-In",
                                    style: TextStyle(
                                        fontSize: 10.sp,
                                        fontWeight: FontWeight.bold),
                                  ),
                                  Text(
                                      homeController
                                          .checkInController.value.text,
                                      style: TextStyle(
                                          fontSize: 12.sp,
                                          fontWeight: FontWeight.w300))
                                ],
                              ),
                              SizedBox(
                                width: 16.w,
                              ),
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text("Check-Out",
                                      style: TextStyle(
                                          fontSize: 10.sp,
                                          fontWeight: FontWeight.bold)),
                                  Text(
                                      homeController
                                          .checkOutController.value.text,
                                      style: TextStyle(
                                          fontSize: 12.sp,
                                          fontWeight: FontWeight.w300))
                                ],
                              ),
                            ],
                          ),
                          Padding(
                            padding: const EdgeInsets.symmetric(vertical: 16.0),
                            child: Text(
                              "Detail Pesanan",
                              style: TextStyle(
                                  fontSize: 12.sp, fontWeight: FontWeight.bold),
                            ),
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Subtotal",
                                style: TextStyle(fontSize: 12.sp),
                              ),
                              Text(
                                  RupiahUtils.beRupiah(
                                      userDataFormController.subtotal.value),
                                  style: TextStyle(fontSize: 12.sp))
                            ],
                          ),
                          const Padding(
                            padding: EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 2,
                            ),
                          ),
                          Row(
                            children: [
                              Expanded(
                                  child: CustomTextField(
                                label: "Masukkan Kode Promo",
                                errorText: "",
                                controller: checkoutController.promoController.value,
                                isPasswordField: false,
                                isRequired: false,
                              )),
                              Padding(
                                padding: const EdgeInsets.all(8.0),
                                child: ElevatedButton(
                                    style: ElevatedButton.styleFrom(
                                        primary: const Color(0xffF0B900)),
                                    onPressed: () => checkoutController.checkPromo(checkoutController.promoController.value.text, userDataFormController.subtotal.value.toString()),
                                    child: checkoutController.isLoading.value ? LoadingAnimationWidget.twoRotatingArc(color: Colors.white, size: 20) : const Text("Terapkan",)),
                              )
                            ],
                          ),
                          Visibility(visible: checkoutController.isVisible.value, child: Text(checkoutController.placeholderCheckPromo.value, style: TextStyle(color: checkoutController.textColor.value))),
                          SizedBox(
                            width: orientation == Orientation.landscape ? 100.h : 100.w,
                            child: ElevatedButton(
                              style: ElevatedButton.styleFrom(
                                  primary: Colors.white,
                                  side: const BorderSide(
                                      width: 1.0, color: Color(0xffF0B900))),
                              onPressed: () {
                                Get.to(() => const PromoList());
                              },
                              child: Padding(
                                padding: const EdgeInsets.all(8.0),
                                child: Text(
                                  "Lihat Daftar Promo",
                                  style: TextStyle(
                                      color: const Color(0xffF0B900),
                                      fontSize: 10.sp,
                                      fontWeight: FontWeight.bold),
                                ),
                              ),
                            ),
                          ),
                          const Padding(
                            padding: EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 2,
                            ),
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Promo Diskon",
                                style: TextStyle(fontSize: 12.sp),
                              ),
                              Text(
                                checkoutController.promoType.value == "Cashback" ? "-Rp 0" : RupiahUtils.beRupiah(checkoutController.totalPromoAmount.value),
                                style: TextStyle(fontSize: 12.sp),
                              ),
                            ],
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Cashback",
                                style: TextStyle(fontSize: 12.sp),
                              ),
                              Text(
                                checkoutController.promoType.value == "Cashback" ? RupiahUtils.beRupiah(checkoutController.totalPromoAmount.value) : "-Rp 0",
                                style: TextStyle(fontSize: 12.sp),
                              ),
                            ],
                          ),
                          const Padding(
                            padding: EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 2,
                            ),
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Total",
                                style: TextStyle(
                                    fontSize: 12.sp,
                                    fontWeight: FontWeight.bold),
                              ),
                              Text(
                                RupiahUtils.beRupiah(checkoutController.total.value),
                                style: TextStyle(
                                    fontSize: 12.sp,
                                    fontWeight: FontWeight.bold),
                              ),
                            ],
                          ),
                          Padding(
                            padding:
                                const EdgeInsets.only(top: 16.0, bottom: 8.0),
                            child: SizedBox(
                              width: orientation == Orientation.landscape
                                  ? 100.h
                                  : 100.w,
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  primary: const Color(0xffF0B900),
                                ),
                                onPressed: () {
                                  bookingController.postBooking(
                                    context, 
                                    authController.userToken.value, 
                                    detailHotelController.detailHotel.value.hotel!.id, 
                                    homeController.checkInController.value.text, 
                                    homeController.checkOutController.value.text, 
                                    checkoutController.total.value.toString(), 
                                    checkoutController.promoController.value.text, 
                                    userDataFormController.detailBooking
                                  );
                                },
                                child: Padding(
                                  padding: const EdgeInsets.all(8.0),
                                  child: Text(
                                    "Proses Booking",
                                    style: TextStyle(
                                        color: Colors.white,
                                        fontSize: 10.sp,
                                        fontWeight: FontWeight.bold),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ]),
                  ),
          ),
        ),
      ),
    );
  }
}

有人可以帮助我确定我的代码有什么问题吗?

Here i am using obx to display an obs variable, at first the error didn't show up, but when i did hot restart, it show this error.

Unhandled Exception: setState() or markNeedsBuild() called during build.
This Obx widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was:
Obx

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

  @override
  Widget build(BuildContext context) {
    var detailHotelController = Get.put(DetailHotelController());
    var homeController = Get.put(HomeController());
    var userDataFormController = Get.put(UserDataFormController());
    var checkoutController = Get.put(CheckoutController());
    var bookingController = Get.put(BookingController());
    var authController = Get.put(AuthController());
    final orientation = MediaQuery.of(context).orientation;
    detailHotelController.getDetailHotel(userDataFormController.hotelId.value);
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        toolbarHeight: 20.w,
        title: Image.asset(
          "assets/turu.png",
          height: 10.h,
        ),
        elevation: 0,
        backgroundColor: Colors.white10,
      ),
      body: Padding(
        padding: const EdgeInsets.only(bottom: 16.0),
        child: SingleChildScrollView(
          child: Obx(
            () => (detailHotelController.isLoading.value)
                ? Center(
                    child: LoadingAnimationWidget.waveDots(
                        color: const Color(0xffF0B900), size: 50))
                : Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            "Tinjau Pemesanan",
                            style: TextStyle(
                                fontSize: 14.sp,
                                color: const Color(0xffF0B900),
                                fontWeight: FontWeight.bold),
                          ),
                          Padding(
                            padding: const EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 1.sp,
                            ),
                          ),
                          Text(
                            detailHotelController.detailHotel.value.hotel!.name,
                            style: TextStyle(
                                fontSize: 13.sp, fontWeight: FontWeight.bold),
                          ),
                          const SizedBox(
                            height: 12,
                          ),
                          Text(
                            detailHotelController
                                .detailHotel.value.hotel!.address
                                .replaceAll("\n", " "),
                            style: TextStyle(fontSize: 10.sp),
                          ),
                          const Padding(
                            padding: EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 2,
                            ),
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            mainAxisSize: MainAxisSize.max,
                            children: [
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text(
                                    "Check-In",
                                    style: TextStyle(
                                        fontSize: 10.sp,
                                        fontWeight: FontWeight.bold),
                                  ),
                                  Text(
                                      homeController
                                          .checkInController.value.text,
                                      style: TextStyle(
                                          fontSize: 12.sp,
                                          fontWeight: FontWeight.w300))
                                ],
                              ),
                              SizedBox(
                                width: 16.w,
                              ),
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text("Check-Out",
                                      style: TextStyle(
                                          fontSize: 10.sp,
                                          fontWeight: FontWeight.bold)),
                                  Text(
                                      homeController
                                          .checkOutController.value.text,
                                      style: TextStyle(
                                          fontSize: 12.sp,
                                          fontWeight: FontWeight.w300))
                                ],
                              ),
                            ],
                          ),
                          Padding(
                            padding: const EdgeInsets.symmetric(vertical: 16.0),
                            child: Text(
                              "Detail Pesanan",
                              style: TextStyle(
                                  fontSize: 12.sp, fontWeight: FontWeight.bold),
                            ),
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Subtotal",
                                style: TextStyle(fontSize: 12.sp),
                              ),
                              Text(
                                  RupiahUtils.beRupiah(
                                      userDataFormController.subtotal.value),
                                  style: TextStyle(fontSize: 12.sp))
                            ],
                          ),
                          const Padding(
                            padding: EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 2,
                            ),
                          ),
                          Row(
                            children: [
                              Expanded(
                                  child: CustomTextField(
                                label: "Masukkan Kode Promo",
                                errorText: "",
                                controller: checkoutController.promoController.value,
                                isPasswordField: false,
                                isRequired: false,
                              )),
                              Padding(
                                padding: const EdgeInsets.all(8.0),
                                child: ElevatedButton(
                                    style: ElevatedButton.styleFrom(
                                        primary: const Color(0xffF0B900)),
                                    onPressed: () => checkoutController.checkPromo(checkoutController.promoController.value.text, userDataFormController.subtotal.value.toString()),
                                    child: checkoutController.isLoading.value ? LoadingAnimationWidget.twoRotatingArc(color: Colors.white, size: 20) : const Text("Terapkan",)),
                              )
                            ],
                          ),
                          Visibility(visible: checkoutController.isVisible.value, child: Text(checkoutController.placeholderCheckPromo.value, style: TextStyle(color: checkoutController.textColor.value))),
                          SizedBox(
                            width: orientation == Orientation.landscape ? 100.h : 100.w,
                            child: ElevatedButton(
                              style: ElevatedButton.styleFrom(
                                  primary: Colors.white,
                                  side: const BorderSide(
                                      width: 1.0, color: Color(0xffF0B900))),
                              onPressed: () {
                                Get.to(() => const PromoList());
                              },
                              child: Padding(
                                padding: const EdgeInsets.all(8.0),
                                child: Text(
                                  "Lihat Daftar Promo",
                                  style: TextStyle(
                                      color: const Color(0xffF0B900),
                                      fontSize: 10.sp,
                                      fontWeight: FontWeight.bold),
                                ),
                              ),
                            ),
                          ),
                          const Padding(
                            padding: EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 2,
                            ),
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Promo Diskon",
                                style: TextStyle(fontSize: 12.sp),
                              ),
                              Text(
                                checkoutController.promoType.value == "Cashback" ? "-Rp 0" : RupiahUtils.beRupiah(checkoutController.totalPromoAmount.value),
                                style: TextStyle(fontSize: 12.sp),
                              ),
                            ],
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Cashback",
                                style: TextStyle(fontSize: 12.sp),
                              ),
                              Text(
                                checkoutController.promoType.value == "Cashback" ? RupiahUtils.beRupiah(checkoutController.totalPromoAmount.value) : "-Rp 0",
                                style: TextStyle(fontSize: 12.sp),
                              ),
                            ],
                          ),
                          const Padding(
                            padding: EdgeInsets.symmetric(vertical: 16.0),
                            child: Divider(
                              color: Colors.grey,
                              height: 2,
                            ),
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Total",
                                style: TextStyle(
                                    fontSize: 12.sp,
                                    fontWeight: FontWeight.bold),
                              ),
                              Text(
                                RupiahUtils.beRupiah(checkoutController.total.value),
                                style: TextStyle(
                                    fontSize: 12.sp,
                                    fontWeight: FontWeight.bold),
                              ),
                            ],
                          ),
                          Padding(
                            padding:
                                const EdgeInsets.only(top: 16.0, bottom: 8.0),
                            child: SizedBox(
                              width: orientation == Orientation.landscape
                                  ? 100.h
                                  : 100.w,
                              child: ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                  primary: const Color(0xffF0B900),
                                ),
                                onPressed: () {
                                  bookingController.postBooking(
                                    context, 
                                    authController.userToken.value, 
                                    detailHotelController.detailHotel.value.hotel!.id, 
                                    homeController.checkInController.value.text, 
                                    homeController.checkOutController.value.text, 
                                    checkoutController.total.value.toString(), 
                                    checkoutController.promoController.value.text, 
                                    userDataFormController.detailBooking
                                  );
                                },
                                child: Padding(
                                  padding: const EdgeInsets.all(8.0),
                                  child: Text(
                                    "Proses Booking",
                                    style: TextStyle(
                                        color: Colors.white,
                                        fontSize: 10.sp,
                                        fontWeight: FontWeight.bold),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ]),
                  ),
          ),
        ),
      ),
    );
  }
}

Can someone help me to identify what's wrong with my code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

还不是爱你 2025-02-07 11:26:25

详细信息hotelcontroller.getDetailHotel(userdataformcontroller.hotelid.value);
这条线导致了问题。

您不应从build方法调用此方法,而应从getxController的生命周期方法之一调用。 oninit()是一个好地方。

有什么问题?

obx小部件就像statefulwidget的一部分,就像每次观察可观察的更改时都调用setState()方法一样。但是,当您热加载加热时,上述控制器方法被调用(因为热重新加载调用build方法,然后也称为上述方法),导致可观察到可观察到的更改,从而在构建中触发重建。

detailHotelController.getDetailHotel(userDataFormController.hotelId.value);
This line is causing the problem.

Instead of calling this method from the build method, you should call it from one of the lifecycle method of the GetxController. onInit() is a good place.

What's wrong?

The Obx widget is like a chunk of StatefulWidget which is like calling the setState() method every time the watched observable changes. But when you hot reload, the above controller method is called (because hot reload calls the build method and then the above method also gets called) causing the observable to change thus triggering rebuild in the middle of a build.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文