Як синхронізувати параметри стану Redux та url хеш-тегів


76

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

Що було б найкращим рішенням за допомогою реакції-маршрутизатора або навіть реакції-маршрутизатора-відновлення ?

Насправді ми не змогли знайти кілька хороших прикладів, коли маршрутизатор реакцій використовується лише для підтримки хеш-тегу URL-адреси, а також оновлює лише один компонент.


4
Чому ви хочете зберегти цей стан у магазині, на відміну від простого використання React Router як джерела істини для параметрів URL-адреси та використання реквізиту, який він вводить у ваш mapStateToProps (state, ownProps)?
Ден Абрамов

2
Оскільки параметри url містять лише шматки лекцій та вибрані глави. У магазині я маю список лекцій та розділів з іменем, кулями та вибраним булевим значенням.
JoKer

1
наприклад, використовувати peterbeshai.com/react-url-query ?
mb21

Відповіді:


149

Думаю, вам не потрібно.
(Вибачте за зневажливу відповідь, але це найкраще рішення з мого досвіду.)

Store - це джерело правди для ваших даних. Це добре.
Якщо ви використовуєте React Router, нехай це буде джерелом правди для вашого стану URL.
Не обов’язково тримати все в магазині.

Наприклад, враховуючи ваш варіант використання:

Оскільки параметри url містять лише шматки лекцій та вибрані глави. У магазині я маю перелік лекцій та розділів з іменем, кулями та вибраним булевим значенням.

Проблема в тому, що ви дублюєте дані. Дані в store ( 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)

4
вибачте, що повернувся так пізно, але останній тиждень я був у відпустці. У мене одне запитання. Ви описали один із способів отримання даних із URL-адреси та їх візуалізації. Як би ви оновили URL-адресу з новими вибраними главами?
JoKer

9
Я б зателефонував browserHistory.push()(звідки browserHistoryімпортується react-router) у творець дій. Можливо, я б використав Redux Thunk, щоб зрозуміти, що відбувається побічний ефект. Я б зателефонував dispatch({ ... }); browserHistory.push(...)всередину.
Дан Абрамов

2
Привіт, Ден. Дякуємо за Redux! Я також вкладаю свої 2 центи в тему і задаю питання. Що робити, якщо логіка переходу стану програми залежить від даних у запиті? Це означає, що це потрібно редукторам, і ви не можете просто так позбутися в магазині.
Олександр Решитко

2
@AlexanderReshytko Оскільки ці дані надходять із “зовнішнього світу”, я б надсилав із ними дії, коли це потрібно . Це не означає, що вам потрібна загальна дія "маршрут змінено" (хоча ви можете відправити її, якщо вважаєте це корисним). Тоді ваші редуктори можуть використовувати цю інформацію, як і зазвичай.
Дан Абрамов

8
Трохи незручно надсилати параметри повторному вибору селекторів, тому можливість отримати поточні параметри URL-адреси з магазину дуже корисна.
Якоб Раск,

3

react-router-redux може допомогти вам ввести URL-адресу для зберігання, тому кожен раз, коли міняється тег хешу, зберігайте також.


23
Він просто надає вам розташування, а не проаналізовані параметри, тому корисний лише, якщо ви не в змозі перевтілити те, що дає вам React Router вручну. Це гарне рішення для синхронізації магазину з діями, щоб запис та повторне відтворення користувацьких сеансів працювали, але насправді це не так корисно для програм, які цього не потребують.
Ден Абрамов
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.