Flutter Provider select - 如何处理复杂的返回类型,如 List 或 Map
Posted
技术标签:
【中文标题】Flutter Provider select - 如何处理复杂的返回类型,如 List 或 Map【英文标题】:Flutter Provider select - How do handle complex returned type like List or Map 【发布时间】:2021-05-31 03:12:05 【问题描述】:我正在尝试使用flutter provider,但当返回的类型是具有未更改引用的复杂对象(如Map
或List
)时,我遇到了context.select()
的问题。
即使我通知模型的侦听器,我的小部件也不会重建,我怀疑这是因为我正在修改我的对象。
这是一个简单的重现代码
class MyModel extends ChangeNotifier
final list = <int>[0, 1, 2, 3, 4, 5];
void push()
// Here I modify the list in place, and even when I call `notifyListeners()`, `MyWidget` won't rebuild
list.add(list.length);
notifyListeners();
class MyScreen extends StatelessWidget
@override
Widget build(BuildContext context)
return ChangeNotifierProvider<MyModel>(
create: (_) => MyModel(),
child: MyWidget(),
);
class MyWidget extends StatefulWidget
@override
_MyWidgetState createState() => _MyWidgetState();
class _MyWidgetState extends State<MyWidget>
@override
Widget build(BuildContext context)
// It is not rebuilt when the list is modified, the widget is rebuilt if I add
// context.select<MyModel, int>((myModel) => myModel.list.length);
// for example
// I suspect it is because the reference of `myModel.list` didn't change
final list = context.select<MyModel, List<int>>((myModel) => myModel.list);
return Container(
child: Column(
children: [
Text(list.join(', ')),
TextButton(
child: const Text('Add'),
onPressed: ()
context.read<MyModel>().push();
// setState(() ); <- I could force the rebuild here too
,
),
],
),
);
当我单击按钮 Add
时,list
会更新,但我的小部件并未重建。
例如,我可以在onPressed
末尾调用setState(() )
来强制重建,但我不想这样做。
处理这个问题的最佳方法是什么?
【问题讨论】:
【参考方案1】:您的list
应该是不可变的:
class MyModel extends ChangeNotifier
List<int> list = <int>[0, 1, 2, 3, 4, 5];
void push()
list = [...list, list.length];
notifyListeners();
否则,对象引用相同,Widget不会重建。
【讨论】:
以上是关于Flutter Provider select - 如何处理复杂的返回类型,如 List 或 Map的主要内容,如果未能解决你的问题,请参考以下文章
flutter_bloc/provider RepositoryProvider vs Provider