Как обрабатывать нормализованное состояние в флаттере / редуксе
Чтобы обеспечить максимально возможную производительность моего приложения, а также тестирование и поддержку кода, я прочитал о нормализации состояния редукции: 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: ...
);
}
)