Как обрабатывать нормализованное состояние в флаттере / редуксе

Чтобы обеспечить максимально возможную производительность моего приложения, а также тестирование и поддержку кода, я прочитал о нормализации состояния редукции: https://redux.js.org/recipes/structuringreducers/normalizingstateshape

Мне было интересно, если что-то подобное возможно с редуксом в флаттер. У меня есть это состояние и вид модели:

class CompetitionState {
 final LoadingStatus status;
 final Competition competition;
}

class Competition {
 final List<Competitor> competitors;
}

class CompetitionPageViewModel {
  final LoadingStatus status;
  final Competition competition;
}

Единственный конкурент внутри List конкурентов могут динамически меняться в зависимости от пользовательского ввода или событий сокета. В настоящее время изменения внутри одного конкурента приведут к полному пересмотру моего ListView как я подключить модель представления, как это:

return StoreConnector<AppState, CompetitionPageViewModel>(
    distinct: true,
    converter: (store) => CompetitionPageViewModel.fromStore(store),
    builder: (context, viewModel) => CompetitionPageContent(viewModel)
);

Есть ли решение этой проблемы? Мой первый подход заключается в том, чтобы также нормализовать состояние, введя EntityState, который содержит все различные нормализованные объекты. Похоже на то, как это отображается здесь: https://medium.com/statuscode/dissecting-twitters-redux-store-d7280b62c6b1

Но с этим я не уверен, как структурировать состояние и редукторы, чтобы иметь возможность работать с отдельными объектами, не вызывая повторного отображения полного списка. А также, как подключить виджет к одному объекту внутри этого состояния. Кто-нибудь имеет опыт с этим и может направить меня в направлении?

1 ответ

Прежде всего, нормализация состояния - это просто парадигма, поэтому она применима в любой форме государственного управления. Первое, что вам нужно для нормализации вашего состояния, это какой-то способ уникальной идентификации модели, которую вы хотите нормализовать (скорее всего, ID), в этом случае Competitor, Вы можете следовать примеру EntityState, на который вы ссылались, для достижения этой цели. По сути, вы бы просто сохранили отображение id в Competitor где-то в вашем штате. Затем вы измените свой Competition класс для:

class Competition {
  final List<int> competitorIds;
}

И затем, в вашем Flutter ListView вы можете прикрепить каждого конкурента к своему StoreConnector вот так:

ListView.builder(
  itemCount: competition.competitorIds.length,
  itemBuilder: (context, index) {
    int competitorId = competition.competitorIds[index];
    return StoreConnector<AppState, Competitor>(
      distinct: true,
      converter: (store) => store.state.entities.allCompetitors[competitorId],
      builder: ...
    );
  }
)
Другие вопросы по тегам