【问题标题】:Flutter Provider select - How do handle complex returned type like List or MapFlutter Provider select - 如何处理复杂的返回类型,如 List 或 Map
【发布时间】:2021-05-31 03:12:05
【问题描述】:

我正在尝试使用flutter provider,但当返回的类型是具有未更改引用的复杂对象(如MapList)时,我遇到了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(() {}) 来强制重建,但我不想这样做。


处理这个问题的最佳方法是什么?

【问题讨论】:

    标签: flutter dart flutter-provider state-management


    【解决方案1】:

    您的list 应该是不可变的:

    class MyModel extends ChangeNotifier {
      List<int> list = <int>[0, 1, 2, 3, 4, 5];
    
      void push() {
        list = [...list, list.length];
        notifyListeners();
      }
    }
    

    否则,对象引用相同,Widget不会重建。

    【讨论】:

      猜你喜欢
      • 2011-11-21
      • 2020-09-01
      • 1970-01-01
      • 2021-08-03
      • 2015-05-05
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 2021-07-11
      相关资源
      最近更新 更多