Ответ 1
Я думаю, вам не нужно.
(Извините за пренебрежительный ответ, но это лучшее решение в моем опыте.)
Магазин является источником правды для ваших данных. Это прекрасно.
Если вы используете React Router, пусть это будет источник истины для вашего состояния URL.
Вам не нужно хранить все в магазине.
Например, учитывая ваш прецедент:
Поскольку параметры url содержат только пули лекций и выбранные главы. В магазине у меня есть список лекций и глав с именем, slug и выбранным логическим значением.
Проблема заключается в том, что вы дублируете данные. Данные в хранилище (chapter.selected
) дублируются в состоянии React Router. Одно решение будет синхронизировать их, но это быстро становится сложным. Почему бы просто не позволить React Router стать источником правды для избранных глав?
Ваше состояние хранилища затем будет выглядеть (упрощено):
{
// Might be paginated, kept inside a "book", etc:
visibleChapterSlugs: ['intro', 'wow', 'ending'],
// A simple ID dictionary:
chaptersBySlug: {
'intro': {
slug: 'intro',
title: 'Introduction'
},
'wow': {
slug: 'wow',
title: 'All the things'
},
'ending': {
slug: 'ending',
title: 'The End!'
}
}
}
Вот оно! Не храните selected
там. Вместо этого пусть React Router справится с этим. В своем обработчике маршрута напишите что-нибудь вроде
function ChapterList({ chapters }) {
return (
<div>
{chapters.map(chapter => <Chapter chapter={chapter} key={chapter.slug} />)}
</div>
)
}
const mapStateToProps = (state, ownProps) => {
// Use props injected by React Router:
const selectedSlugs = ownProps.params.selectedSlugs.split(';')
// Use both state and this information to generate final props:
const chapters = state.visibleChapterSlugs.map(slug => {
return Object.assign({
isSelected: selectedSlugs.indexOf(slug) > -1,
}, state.chaptersBySlug[slug])
})
return { chapters }
}
export default connect(mapStateToProps)(ChapterList)