2016-04-19 20 views
63

Abbiamo un elenco di lezioni e capitoli in cui l'utente può selezionarli e deselezionarli. Le due liste sono memorizzate in un negozio redux. Ora vogliamo mantenere una rappresentazione degli slider e degli slug di capitolo selezionati nel tag hash dell'URL e qualsiasi modifica all'URL dovrebbe cambiare anche il negozio (sincronizzazione a due vie).Come sincronizzare i parametri del tag hash redux e url

Quale sarebbe la soluzione migliore utilizzando react-router o react-router-redux?

Non siamo riusciti a trovare alcuni buoni esempi in cui il router di risposta viene utilizzato solo per mantenere il tag hash di un url e aggiorna anche solo un componente.

Grazie !!!

+3

Perché vuoi mantenere questo stato nel negozio, piuttosto che semplicemente utilizzando Reagire Router come fonte di verità per i parametri URL, e utilizzando gli oggetti di scena Inserisce nel vostro mapStateToProps (state, ownProps)? –

+2

Poiché i parametri dell'URL contengono solo gli slug delle lezioni e i capitoli selezionati. Nel negozio ho un elenco di lezioni e capitoli con un nome, slug e un valore booleano selezionato. – JoKer

+0

ad es. utilizzare https://peterbeshai.com/react-url-query/? – mb21

risposta

126

Penso che non sia necessario.
(Ci scusiamo per una risposta sprezzante, ma è la soluzione migliore nella mia esperienza.)

Il negozio è la fonte della verità per i dati. Questo va bene.
Se si utilizza React Router, lasciare che sia la fonte della verità per lo stato dell'URL.
Non devi tenere tutto nel negozio.

Per esempio, considerando il tuo caso d'uso:

Poiché i parametri URL contengono solo le lumache delle lezioni e dei capitoli che sono selezionati. Nel negozio ho un elenco di lezioni e capitoli con un nome, slug e un valore booleano selezionato.

Il problema è che stai duplicando i dati. I dati nel negozio (chapter.selected) sono duplicati nello stato React Router. Una soluzione sarebbe la loro sincronizzazione, ma questo diventa rapidamente complesso. Perché non lasciare che React Router sia la fonte della verità per i capitoli selezionati?

tuo stato negozio sarebbe quindi simile (semplificato):

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

Questo è tutto! Non conservare selected lì. Invece lascia che React Router lo gestisca. Nel vostro gestore di percorso, scrivere qualcosa come

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

Grazie a @dan per la tua risposta dettagliata. Proverò ad applicarlo e riferire come ha funzionato. – JoKer

+4

scusa per essere tornato così tardi ma ero in vacanza l'ultima settimana. Ho una domanda. Hai descritto un modo per ottenere i dati dall'URL e renderli.Come aggiorneresti l'url con i nuovi capitoli selezionati? – JoKer

+8

Chiamerei 'browserHistory.push()' (dove 'browserHistory' è importato da' react-router') nell'action creator. Probabilmente userò Redux Thunk per chiarire che c'è un effetto collaterale in corso. Chiamerei 'dispatch ({...}); browserHistory.push (...) 'al suo interno. –

3

react-router-redux può aiutarti a iniettare il materiale dell'URL da archiviare, quindi ogni volta che si cambia tag hash, memorizza anche.

+13

Ti dà solo la posizione, non i parametri analizzati, quindi è di utilità limitata a meno che tu non stia bene con il reimplementare ciò che React Router ti dà manualmente. È una buona soluzione per mantenere lo store sincronizzato con le azioni * in modo che la registrazione e la ripetizione delle sessioni utente funzionino *, ma non è così utile per le app che non ne hanno bisogno. –

Problemi correlati