面试题答案
一键面试1. 使用Provider的Selectors优化状态更新及避免不必要重建的原理
- 原理概述:
Provider
中的Selector
允许我们在Widget
树中选择状态的特定部分,并仅当该部分状态发生变化时才重建依赖它的Widget
。这与普通的Consumer
不同,普通Consumer
会在其所依赖的整个状态对象发生变化时就重建,而不管状态对象内部具体哪些数据改变了。
2. 优化示例
- 简单示例:假设我们有一个
Counter
状态类,其中包含两个属性count
和name
,但某个Widget
仅关心count
的变化。
class Counter {
int count;
String name;
Counter({this.count = 0, this.name = 'default'});
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Selector<Counter, int>(
selector: (_, counter) => counter.count,
builder: (context, count, child) {
return Text('Count: $count');
},
);
}
}
- 复杂Widget树结构应用:考虑一个电商应用,有一个
Cart
状态类,包含购物车商品列表List<Product>
和用户信息UserInfo
。假设在CartPage
的Widget
树中有一个CartItemList
Widget
只关心购物车商品列表的变化,而不关心用户信息的变化。
class Product {}
class UserInfo {}
class Cart {
List<Product> products;
UserInfo userInfo;
Cart({required this.products, required this.userInfo});
}
class CartItemList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Selector<Cart, List<Product>>(
selector: (_, cart) => cart.products,
builder: (context, products, child) {
return ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
return ListTile(title: Text('Product ${products[index]}'));
},
);
},
);
}
}
在这个例子中,即使 UserInfo
发生变化,只要 products
列表没有变化,CartItemList
就不会重建,从而提升了性能。