面试题答案
一键面试- 细粒度状态拆分
- 将不同类型的状态拆分成多个独立的
ChangeNotifier
或ValueNotifier
。这样,当某个状态变化时,只有依赖该状态的部分会重建。 - 例如,假设有一个应用需要管理用户信息和购物车信息这两种不同类型的状态。
- 首先定义用户信息的
ChangeNotifier
:
- 将不同类型的状态拆分成多个独立的
class UserInfo with ChangeNotifier {
String _name = '';
String get name => _name;
set name(String newName) {
_name = newName;
notifyListeners();
}
}
- 然后定义购物车信息的
ChangeNotifier
:
class CartInfo with ChangeNotifier {
List<String> _items = [];
List<String> get items => _items;
void addItem(String item) {
_items.add(item);
notifyListeners();
}
}
- 使用
Select
进行精准依赖- 在使用
Provider
的页面中,通过Select
来指定只依赖特定状态的一部分,从而避免整个页面因状态变化而重建。 - 例如,有一个展示用户名字的页面,只依赖
UserInfo
中的name
属性:
- 在使用
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class UserNamePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('User Name Page'),
),
body: Center(
child: Select<UserInfo, String>(
selector: (_, userInfo) => userInfo.name,
builder: (_, name, __) => Text('User Name: $name'),
),
),
);
}
}
- 对于购物车页面,只关心购物车中的商品列表:
class CartPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Cart Page'),
),
body: Select<CartInfo, List<String>>(
selector: (_, cartInfo) => cartInfo.items,
builder: (_, items, __) => ListView.builder(
itemCount: items.length,
itemBuilder: (_, index) => ListTile(
title: Text(items[index]),
),
),
),
);
}
}
- 顶层状态管理
- 在
main.dart
中,通过MultiProvider
将所有的状态管理类提供出来:
- 在
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => UserInfo()),
ChangeNotifierProvider(create: (_) => CartInfo()),
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: UserNamePage(),
routes: {
'/cart': (context) => CartPage(),
},
);
}
}
通过以上设计,不同页面可以精准依赖各自需要的状态,当某个状态变化时,只有依赖该状态的页面部分会重建,提高了应用的性能。