Подтвердить что ты не робот

Как синхронизировать параметры состояния Redux и URL-адреса хэша

У нас есть список лекций и глав, где пользователь может выбрать и отменить выбор. Два списка хранятся в магазине redux. Теперь мы хотим сохранить представление выбранных лекционных слизней и гласных пробок в хэш-теге URL-адреса, и любые изменения в URL-адресе также должны изменить хранилище (двухсторонняя синхронизация).

Каким будет лучшее решение, использующее react-router или даже react-router-redux?

Мы не смогли найти хороших примеров, когда реагирующий маршрутизатор используется только для поддержки хэш-тега URL-адреса, а также только для обновления одного компонента.

Спасибо!!!

4b9b3361

Ответ 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)

Ответ 2

react-router-redux может помочь вам вставлять материал url для хранения, поэтому каждый раз, когда тэг hash изменяется, также сохраняйте.