Home > OS >  Consumer works, Selector doesn't, why?
Consumer works, Selector doesn't, why?

Time:03-23

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?

CodePudding user response:

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();
  • Related