Flutter GetX Obx [Get] 检测到 GetX 的不当使用。您应该只对将要更新的特定小部件使用 GetX 或 Obx

Flutter GetX Obx [Get] the improper use of a GetX has been detected. You should only use GetX or Obx for the specific widget that will be updated

我正在使用 GetX 并大量使用 Obx 以反应方式通过 UI 进行构建,但是,每当我需要对我的 Rx 变量进行一些处理时,我总是会遇到麻烦,结果是此错误:

      [Get] the improper use of a GetX has been detected.
      You should only use GetX or Obx for the specific widget that will be updated.
      If you are seeing this error, you probably did not insert any observable variables into GetX/Obx
      or insert them outside the scope that GetX considers suitable for an update
      (example: GetX => HeavyWidget => variableObservable).
      If you need to update a parent widget and a child widget, wrap each one in an Obx/GetX.

我的 Widget build() 函数如下所示:

    // class ProductDetailScreen extends GetWidget<ProductDetailScreenController>
    // late final CartListController _cartListController =
          Get.find<CartListController>();
    // ..

    Widget build(BuildContext context) {
        RxProductData data = controller.productData;
        _cartItemModel = _cartListController.rxCart.getItem(data.id); // 2. I need widget to rebuild whenever rxCart changed, since the _cartItemModel returned might have changed. (eg: _cartItemModel.rxQuantity changed)
        return Obx(() => Scaffold( // 1a. This Obx...
            appBar: AppBar(
              leading: IconButton(
                  onPressed: () {
                    Get.back();
                  },
                  icon: const Icon(Icons.arrow_back)),
              title: const Text('New Product Detail Screen'),
            ),
            body: controller.loadingStatus.isLoading // 1b. ...is for loadingStatus which is an RxStatus, but it caused the error to be thrown, if I put: body: Obx(() => controller.loadingStatus.isLoading : ... ), it will not throw but when loadingStatus changed it won't refresh either
                ? const CircularProgressIndicator.adaptive()
                : Container(
                    color: Colors.pink[100],
                    child: Center(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: <Widget>[
                          Text(
                              'Quantity Func: ${_cartListController.getQuantityInCart(productId: data.id)}'),
                          Text('Qty: ${_cartEntry.quantity.value}'),
                        ],
                      ),
                    ))));
      }
    class ProductDetailScreenController extends GetxController {
      late final ProductListController _productListController =
          Get.find<ProductListController>();
      late final CartListController _cartListController =
          Get.find<CartListController>();

      RxStatus loadingStatus = RxStatus.loading();
      late RxProductData productData;
      late RxCartEntryModel cartEntry;

      Future loadData(String productId) async {
        loadingStatus = RxStatus.loading();
        ProductItemModel? productExist =
            _productListController.getProductById(productId);
        if (productExist != null) {
          productData = productExist.rx;
        } else {
            loadingStatus = RxStatus.error();
            productData = RxProductItemModel();
            return;
        }

        loadingStatus = RxStatus.success();
      }
    }

所以我的主要问题(代码注释中的 1)实际上是导致错误的 1a 和 1b,如果我需要对 RxVariables 进行进一步处理,我应该如何放置 Obx?

我的第二个问题(代码注释中的 2)是我是否需要我的小部件重新执行整个 build() 函数并根据 Rx 更改再次获取数据,但是 Rx 没有直接呈现在任何返回的小部件

您错误地更改了 loadingStatusRxStatus.success() 是一个构造函数,调用它将 return 一个 RxStatus 的新实例,从而完全替换您的 Rx 变量。因此,您的 Obx 仍将保留对旧 loadingStatus 的引用(它从未也不能更改),因此您的 Obx 小部件将永远不会更新

正确使用RxStatus是关键。您可以查看我在评论中提到的这些参考资料:

https://evandrmb.medium.com/make-your-code-clean-with-getx-statemixin-80c69e502cf4

https://gist.github.com/eduardoflorence/8b5a0b5139aadb4c31ddde1d28da9323