Consumer 有效,Selector 无效,为什么?

发布于 2025-01-16 06:03:58 字数 1327 浏览 2 评论 0原文

这是一个带有提供程序的 flutter 小部件:

class FixtureList extends StatelessWidget {
  const FixtureList({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Consumer<AppState>(
      builder: (context, appState, _) => ListView(
        children: appState.fixtures.isNotEmpty
            ? appState.fixtures
                .map((e) => FixtureListItem(
                      fixtureId: e.name,
                    ))
                .toList()
            : [],
      ),
    );
  }
}

效果很好,但我只使用 appState.fixtures,所以为什么不使用 Selector 只监听该部分,如下所示

  @override
  Widget build(BuildContext context) {
    return Selector<AppState, List<Fixture>>(
      selector: (context, appState) => appState.fixtures,
      builder: (context, fixtures, _) => ListView(
        children: fixtures.isNotEmpty
            ? fixtures
                .map((e) => FixtureListItem(
                      fixtureId: e.name,
                    ))
                .toList()
            : [],
      ),
    );
  }

:不起作用,在 AppState 中调用 notifyListeners 时,ListWiew 不会重新渲染。

知道出了什么问题吗?

Here's a flutter widget with provider:

class FixtureList extends StatelessWidget {
  const FixtureList({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Consumer<AppState>(
      builder: (context, appState, _) => ListView(
        children: appState.fixtures.isNotEmpty
            ? appState.fixtures
                .map((e) => FixtureListItem(
                      fixtureId: e.name,
                    ))
                .toList()
            : [],
      ),
    );
  }
}

Works great, but I'm using only appState.fixtures, so why not listen only to that part with a Selector, like so:

  @override
  Widget build(BuildContext context) {
    return Selector<AppState, List<Fixture>>(
      selector: (context, appState) => appState.fixtures,
      builder: (context, fixtures, _) => ListView(
        children: fixtures.isNotEmpty
            ? fixtures
                .map((e) => FixtureListItem(
                      fixtureId: e.name,
                    ))
                .toList()
            : [],
      ),
    );
  }

This doesn't work, the ListWiew is not re-rendered when notifyListeners is called in AppState.

Any idea what's wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

趴在窗边数星星i 2025-01-23 06:03:58

您在评论中提到您只是在灯具列表上调用 add 。这意味着您实际上每次都会返回相同的 List 对象。然后,选择器会比较对同一对象的两个引用,得出结论它们是相同的,并且不会重建您的小部件。

为了使 Selector 按预期工作,每当您想要修改其内容时,您都需要创建一个新的 List 实例:

fixtures = [...fixtures, fixtureToAdd];
notifyListeners();

You mentioned in comments that you're just calling add on your fixtures list. This means that you're actually returning the same List<Fixture> object every time. The Selector then compares two references to the same object, concludes that they're the same, and doesn't rebuild your widget.

To make Selector work as intended, you will need to create a new List<Fixture> instance whenever you want to modify its contents:

fixtures = [...fixtures, fixtureToAdd];
notifyListeners();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文