从 child 更改状态时小部件不使用 riverpod 重建
Widget don't rebuild with riverpod when changing state from child
我正在使用 riverpod 开发uild 我的应用程序,我正在努力开发uild 一个简单的添加到最喜欢的功能。我有一个产品列表和一个 child 消费者小部件,它是一张带有添加到收藏夹按钮的卡片。
当我更改 child 卡中的产品状态时,ui 不会 rebuild。
这里是 git 存储库 https://github.com/nisa10880/riverpod_difficulties
Consumer(
builder: (context, watch, child) =>
watch(getProductsFutureProvider).when(
data: (p) {
final products = watch(productListStateProvider).state;
return ListView.builder(
itemCount: products.length,
itemBuilder: (BuildContext context, int index) =>
ProductCard(product: products[index]));
},
loading: () => CircularProgressIndicator(),
error: (e, s) => Text(e)))
final productServiceProvider = Provider<ProductService>((ref) {
return ProductService();
});
class ProductService {
ProductService();
Future<List<ProductModel>> getAllProducts() async {
await Future.delayed(Duration(seconds: 1));
return [
ProductModel(id: '1', title: 'product 1', isFavorite: false),
ProductModel(id: '2', title: 'product 2', isFavorite: false),
ProductModel(id: '3', title: 'product 3', isFavorite: false),
ProductModel(id: '4', title: 'product 4', isFavorite: false)
];
}
}
final productListStateProvider = StateProvider<List<ProductModel>>((ref) {
return [];
});
final getProductsFutureProvider =
FutureProvider.autoDispose<List<ProductModel>>((ref) async {
ref.maintainState = true;
final evtentService = ref.watch(productServiceProvider);
final products = await evtentService.getAllProducts();
ref.read(productListStateProvider).state = products;
return products;
});
class ProductCard extends ConsumerWidget {
final ProductModel product;
const ProductCard({
@required this.product,
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context, ScopedReader watch) {
return Card(
child: Column(
children: <Widget>[
Text(product.title),
product.isFavorite
? IconButton(
icon: Icon(Icons.favorite),
color: Colors.red,
onPressed: () {
product.isFavorite = !product.isFavorite;
},
)
: IconButton(
icon: Icon(Icons.favorite_border),
color: Colors.black54,
onPressed: () {
product.isFavorite = !product.isFavorite;
},
)
],
));
}
}
问题是你正在更新 ProductModel
的内部值而不是状态(状态是 List<ProductModel>
)所以它不会触发重建,你要么尝试像这个:
onPressed: () {
List<ProductModel> productList = context.read(productListStateProvider).state;
int index = productList.indexWhere((e) => e.id == product.id);
productList[index].isFavorite = !product.isFavorite;
context.read(productListStateProvider).state = productList;
},
或者您尝试使用 ChangeNotifierProvider,以便在您觉得对某个值进行了更改时可以调用 notifyListeners()
我正在使用 riverpod 开发uild 我的应用程序,我正在努力开发uild 一个简单的添加到最喜欢的功能。我有一个产品列表和一个 child 消费者小部件,它是一张带有添加到收藏夹按钮的卡片。
当我更改 child 卡中的产品状态时,ui 不会 rebuild。
这里是 git 存储库 https://github.com/nisa10880/riverpod_difficulties
Consumer(
builder: (context, watch, child) =>
watch(getProductsFutureProvider).when(
data: (p) {
final products = watch(productListStateProvider).state;
return ListView.builder(
itemCount: products.length,
itemBuilder: (BuildContext context, int index) =>
ProductCard(product: products[index]));
},
loading: () => CircularProgressIndicator(),
error: (e, s) => Text(e)))
final productServiceProvider = Provider<ProductService>((ref) {
return ProductService();
});
class ProductService {
ProductService();
Future<List<ProductModel>> getAllProducts() async {
await Future.delayed(Duration(seconds: 1));
return [
ProductModel(id: '1', title: 'product 1', isFavorite: false),
ProductModel(id: '2', title: 'product 2', isFavorite: false),
ProductModel(id: '3', title: 'product 3', isFavorite: false),
ProductModel(id: '4', title: 'product 4', isFavorite: false)
];
}
}
final productListStateProvider = StateProvider<List<ProductModel>>((ref) {
return [];
});
final getProductsFutureProvider =
FutureProvider.autoDispose<List<ProductModel>>((ref) async {
ref.maintainState = true;
final evtentService = ref.watch(productServiceProvider);
final products = await evtentService.getAllProducts();
ref.read(productListStateProvider).state = products;
return products;
});
class ProductCard extends ConsumerWidget {
final ProductModel product;
const ProductCard({
@required this.product,
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context, ScopedReader watch) {
return Card(
child: Column(
children: <Widget>[
Text(product.title),
product.isFavorite
? IconButton(
icon: Icon(Icons.favorite),
color: Colors.red,
onPressed: () {
product.isFavorite = !product.isFavorite;
},
)
: IconButton(
icon: Icon(Icons.favorite_border),
color: Colors.black54,
onPressed: () {
product.isFavorite = !product.isFavorite;
},
)
],
));
}
}
问题是你正在更新 ProductModel
的内部值而不是状态(状态是 List<ProductModel>
)所以它不会触发重建,你要么尝试像这个:
onPressed: () {
List<ProductModel> productList = context.read(productListStateProvider).state;
int index = productList.indexWhere((e) => e.id == product.id);
productList[index].isFavorite = !product.isFavorite;
context.read(productListStateProvider).state = productList;
},
或者您尝试使用 ChangeNotifierProvider,以便在您觉得对某个值进行了更改时可以调用 notifyListeners()