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


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

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

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

спасибо!!!

2 68

2 ответа:

Я думаю, что вам это не нужно.
(Простите за пренебрежительный ответ, но это лучшее решение в моем опыте.)

хранилище является источником истины для ваших данных. Это нормально.
Если вы используете маршрутизатор React, пусть он будет источником истины для вашего состояния 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 там. Вместо этого пусть реагирует маршрутизатор обрабатывать его. В обработчике маршрута напишите что-то вроде

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)

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