web-dev-qa-db-fra.com

Comment synchroniser les paramètres d'état des étiquettes de hachage Redl et de l'URL

Nous avons une liste de conférences et de chapitres où l’utilisateur peut les sélectionner et les désélectionner. Les deux listes sont stockées dans un magasin Redux. Nous voulons maintenant conserver une représentation des slugs de lecture et des chapitres sélectionnés dans la balise de hachage de l'URL. Toute modification apportée à l'URL devrait également modifier le magasin (synchronisation dans les deux sens).

Quelle serait la meilleure solution en utilisant react-router ou même react-router-redux ?

Nous ne trouvions pas vraiment de bons exemples dans lesquels le routeur de réaction n’est utilisé que pour conserver la balise de hachage d’une URL et pour mettre à jour un seul composant.

Merci!!!

70
JoKer

Je pense que tu n’en as pas besoin.
(Désolé pour une réponse dédaigneuse mais c’est la meilleure solution de mon expérience.)

Store est la source de vérité de vos données. C'est bon.
Si vous utilisez React Router, laissez-le être la source de la vérité pour votre état d'URL.
Vous n’avez pas à tout garder dans le magasin.

Par exemple, en considérant votre cas d'utilisation:

Parce que les paramètres url ne contiennent que les notes des cours et les chapitres sélectionnés. Dans le magasin, j'ai une liste de conférences et de chapitres avec un nom, un slug et une valeur booléenne sélectionnée.

Le problème est que vous dupliquez les données. Les données dans le magasin (chapter.selected) est dupliqué dans le React état du routeur. Une solution serait de les synchroniser, mais cela devient rapidement complexe. Pourquoi ne pas laisser simplement React le routeur être le source de vérité pour certains chapitres?

L'état de votre magasin ressemblerait alors à (simplifié):

{
  // 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!'
    }
  }
}

C'est ça! Ne stockez pas selected ici. Laissez plutôt React Le routeur le gérer. Dans votre gestionnaire d'itinéraire, écrivez quelque chose comme:

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)
144
Dan Abramov

react-router-redux peut vous aider à injecter le contenu de l'URL à stocker, donc chaque fois que l'étiquette de hachage est modifiée, stockez également.

4
David Guan