78 votes

Comment synchroniser l'état Redux et les paramètres de l'url hash tag

Nous disposons d'une liste de conférences et de chapitres que l'utilisateur peut sélectionner et désélectionner. Les deux listes sont stockées dans un magasin redux. Maintenant, nous voulons garder une représentation des slugs de conférences et de chapitres sélectionnés dans la balise hash de l'url et tout changement de l'url devrait changer le magasin aussi (synchronisation bidirectionnelle).

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

Nous n'avons pas pu trouver de bons exemples où le react router n'est utilisé que pour maintenir le hash tag d'une url et ne met à jour qu'un seul composant.

4 votes

Pourquoi voulez-vous conserver cet état dans le magasin, plutôt que d'utiliser React Router comme source de vérité pour les paramètres d'URL, et d'utiliser les props qu'il injecte dans votre mapStateToProps(state, ownProps) ?

2 votes

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

1 votes

Par exemple, utiliser peterbeshai.com/react-url-query ?

152voto

Dan Points 16670

Je pense que ce n'est pas nécessaire.
(Désolé pour cette réponse dédaigneuse, mais c'est la meilleure solution d'après mon expérience).

Le magasin est la source de vérité pour vos données. Cela ne pose pas de problème.
Si vous utilisez React Router, laissez-le être la source de vérité pour l'état de votre URL.
Il n'est pas nécessaire de tout conserver dans le magasin.

Prenons l'exemple de votre cas d'utilisation :

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

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

L'état de votre magasin ressemblerait alors à ce qui suit (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 tout ! Ne stockez pas selected là. Laissez plutôt React Router s'en charger. Dans votre gestionnaire de route, é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)

0 votes

Merci @dan pour votre réponse détaillée. Je vais essayer de l'appliquer et de faire un rapport sur son fonctionnement.

4 votes

Désolé de revenir si tard, mais j'étais en vacances la semaine dernière. J'ai une question à vous poser. Vous avez décrit une méthode qui consiste à récupérer les données de l'url et à les restituer. Comment mettre à jour l'url avec les nouveaux chapitres sélectionnés ?

9 votes

J'appellerais browserHistory.push() (où browserHistory est importé de react-router ) dans le créateur d'action. J'utiliserais probablement Redux Thunk pour indiquer clairement qu'il y a un effet de bord. J'appellerais dispatch({ ... }); browserHistory.push(...) à l'intérieur.

3voto

David Guan Points 2118

react-router-redux peut vous aider à injecter l'url dans le magasin, de sorte que chaque fois que le hash tag est modifié, le magasin l'est aussi.

23 votes

Il ne vous donne que l'emplacement, pas les paramètres analysés, il est donc d'une utilité limitée à moins que vous ne soyez prêt à réimplémenter ce que React Router vous donne manuellement. C'est une bonne solution pour garder le magasin synchronisé avec les actions. pour que l'enregistrement et la relecture des sessions d'utilisateurs fonctionnent mais ce n'est pas vraiment utile pour les applications qui n'en ont pas besoin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X