当值更改时,Flutter HookWidget 不会重建
Flutter HookWidget doesn't rebuild when values changed
这里我使用了非常简单的 HookWidget
和 Riverpod
,当我调用 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 并通知其侦听器按上述方式工作。
这里我使用了非常简单的 HookWidget
和 Riverpod
,当我调用 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 并通知其侦听器按上述方式工作。