当值更改时,Flutter HookWidget 不会重建

Flutter HookWidget doesn't rebuild when values changed

这里我使用了非常简单的 HookWidgetRiverpod,当我调用 StateNotifierProvider 的一些方法时,例如 increment 我希望我使用的小部件 useProvider 再次重建,例如:

class MyHomePage extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final _orderProvider = useProvider(orderStateNotifierProvider.notifier);
    final List<SelectedProductServices> _serviceList = _orderProvider.getServices();
    return Scaffold(
        appBar: AppBar(
          title: Text('test'),
        ),
        body: Center(
          child:
          Consumer(
            builder: (_, watch, __) {
              return Column(
                children: <Widget>[
                  //...
                    GestureDetector(
                      onTap: () => _orderProvider.increment(productId: 1, serviceId: 1),
                      child: Container(
                          width: 200.0,
                          height: 50.0,
                          child: Text('ADD')),
                    )
                 //...
                ],
              );
            },
          ),
        ));
  }
}

这里点击按钮 increment 工作正常,但 _orderProvider 不触发屏幕,我尝试同时使用 Consumer 和不使用 Consumer .始终无法重建屏幕

在方法中尝试创建 List<SelectedProductServices> 的新实例,如下所示:

  void increment({int productId,int serviceId}) {
    state = [// Generate a new list with current items in state
      for (final selectedService in state)
        if (selectedService.id == productId&&selectedService.sId==serviceId) 
          SelectedProductServices(
           //Create a new object with the updated internal state
          )
        else
          selectedService,
    ];
  }

Dart 通过引用而不是值来比较它的对象,当你改变 List 的内部状态时,它在内存中占用的引用是相同的,无论它拥有多少项目。 如果列表保存在 class 中,您可以覆盖 == 方法以使用 DeepCollectionEquality 比较 List<SelectedProductServices> 但是当您直接使用 List 对象时,您只能创建内存中具有不同引用的新列表,以便 oldState!=newState

注意:您应该使所有修改内部状态的方法和您想要更新 UI 并通知其侦听器按上述方式工作。