Here i used very simple HookWidget
and Riverpod
, when i call some methods of StateNotifierProvider
such as increment
i expect my widgets which i used useProvider
rebuild again, for example:
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')),
)
//...
],
);
},
),
));
}
}
here after clicking on button increment
work fine, but _orderProvider
doesn't trigger screen, i tried to use both of using Consumer
and not using Consumer
. in all time screen can't rebuild
In the methods try to create new instances of List<SelectedProductServices>
like here:
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 compares its objects by reference, not by value and when you mutate the internal state of the List the reference it occupies in memory is the same regardless of the amount of items it has.
If the list was held inside a class you could override the ==
method to compare the List<SelectedProductServices>
using DeepCollectionEquality
but when you are working directly with the List object you can only create a new list with a different reference in memory so that oldState!=newState
Note: you should make all methods that modify internal state and that you want to update the UI and notify its listeners to work as above.