Jak zsynchronizować Redux state i Url hash tag params

Mamy listę wykładów i rozdziałów, w których użytkownik może wybrać i odznaczyć je. Obie listy są przechowywane w sklepie redux. Teraz chcemy zachować reprezentację wybranych slugów wykładów i rozdziałów w tagu hash adresu url, a wszelkie zmiany w adresie URL powinny również zmienić sklep (dwukierunkowa synchronizacja).

Jakie byłoby najlepsze rozwiązanie przy użyciu react-router lub nawet react-router-redux ?

Nie mogliśmy znaleźć dobrych przykładów, gdzie react router jest używany tylko do utrzymywania znacznika skrótu adresu url, a także aktualizuje tylko jeden komponent.

Dzięki!!!

Author: Dan Abramov, 2016-04-19

2 answers

Myślę, że nie musisz.
(Przepraszam za lekceważącą odpowiedź, ale to najlepsze rozwiązanie z mojego doświadczenia.)

Sklep jest źródłem prawdy dla Twoich danych. W porządku.
Jeśli używasz routera Reactowego, niech będzie on źródłem prawdy dla Twojego stanu URL.
Nie musisz trzymać wszystkiego w sklepie.

Na przykład, biorąc pod uwagę Twój przypadek użycia:

Ponieważ parametry url zawierają tylko fragmenty wybranych wykładów i rozdziałów. W sklep mam listę wykładów i rozdziałów z nazwą, slug i wybraną wartością logiczną.

Problem w tym, że powielasz dane. Dane w store (chapter.selected) są duplikowane w stanie Reactowego routera. Jednym z rozwiązań byłaby ich synchronizacja, ale to szybko robi się skomplikowane. Dlaczego po prostu nie pozwolić, aby React Router był źródłem prawdy dla wybranych rozdziałów?

Stan twojego sklepu będzie wyglądał następująco (uproszczony):

{
  // 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!'
    }
  }
}
To jest to! Nie przechowuj selected tam. Zamiast tego niech React Router sobie z tym poradzi. Napisz coś w stylu
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)
 136
Author: Dan Abramov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-30 15:28:05

react-router-redux może pomóc w wstrzyknięciu adresu URL do przechowywania, więc za każdym razem, gdy zmieniany jest tag hash, przechowuj również.

 4
Author: David Guan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-20 10:29:33