2016-06-22 40 views
20

Dato il mio stato Redux iniziale è:React-Redux di oggetti complessi (profondità) Stato

const state = { 
    currentView: 'ROOMS_VIEW', 
    navbarLinks: List([ 
    {name: 'Rooms', key: 'ROOMS_VIEW'}, 
    {name: 'Dev', key: ''} 
    ]), 
    roomListsSelected: {group: 0, item: 0}, 
    roomLists: [ 
    { 
     name: "Filters", 
     expanded: true, 
     listItems: [ 
     { icon: 'images/icon-warning.svg', name: 'Alerts', filter: room => room.hasAlert }, 
     { icon: 'images/icon-playlist.svg', name: 'In Progress', filter: room => room.progress > 20 }, 
     { icon: 'images/icon-playlist.svg', name: 'Almost Done', filter: room => room.progress > 90 }, 
     { icon: 'images/icon-playlist.svg', name: 'Complete', filter: room => room.status === 'complete' }, 
     { icon: 'images/icon-playlist.svg', name: 'Recently Completed', filter: room => false }, 
     { icon: 'images/icon-playlist.svg', name: 'All Rooms', filter: room => true } 
     ] 
    } 
    ], 
    rooms: List(generateRooms()) 
} 

ho bisogno di fare un riduttore che fa questo:

state.roomList[n].expanded = !state.roomList[n].expanded 

Sono nuovo di utilizzare un Redux il flusso di lavoro e il modo migliore per risolvere questo problema è rendere roomList un oggetto immutable.js o scrivere del codice per creare un clone profondo del mio oggetto di stato.

Anche state.roomList avrà nuovi dati trasmessi da funzionalità future.

Summery/Domanda: Qual è il modo migliore per restituire un nuovo oggetto di stato in un riduttore quando si effettuano modifiche come questo in profondità nello stato o si deve modificare la struttura dell'oggetto stato Redux?

Cosa ho fatto Alla fine, Immutable sembra la strada da percorrere. Ci sono alcuni trucchi con Immutable per ridurre i tempi di rendering e soddisfa tutti i requisiti del progetto. Inoltre è abbastanza presto nel progetto di utilizzare una nuova libreria senza apportare modifiche importanti.

+0

Hai una domanda? –

+1

Qual è il modo migliore per restituire un nuovo oggetto stato in un riduttore quando si apportano modifiche come questo in profondità nello stato, o devo cambiare la struttura dell'oggetto stato Redux? –

risposta

27

In primo luogo, Redux idiomatico ti incoraggia a "normalizzare" il tuo stato e ad appiattirlo il più possibile. Utilizza gli oggetti immessi dagli ID oggetto per consentire la ricerca diretta di elementi, utilizzare matrici di ID per indicare l'ordine e ovunque sia necessario fare riferimento a un elemento, memorizza solo l'ID dell'altro elemento anziché i dati effettivi. Ciò consente di effettuare ricerche e aggiornamenti più semplici di oggetti nidificati. Vedi the Redux FAQ question on nested data.

Inoltre, sembra che tu stia attualmente memorizzando un numero di funzioni direttamente nello stato di Redux. Tecnicamente lo funziona, ma non è assolutamente idiomatico e interromperà funzionalità come il debug nel tempo, quindi è fortemente scoraggiato. Le Domande frequenti su Redux forniscono ulteriori informazioni su why storing non-serializable values in your Redux state is a bad idea.

edit:

Come follow-up, di recente ho aggiunto una nuova sezione per la documentazione Redux, sul tema della "Structuring Reducers".In particolare, questa sezione include i capitoli "Normalizing State Shape" e "Updating Normalized Data" e "Immutable Update Patterns".

+1

Questa sembra la risposta più "corretta" e l'archiviazione di funzioni letterali nello stato era una soluzione rapida che cambierà in un metodo più tradizionale prima del rilascio. –

+0

Sicuro. Un approccio correlato che puoi guardare è memorizzare un qualche tipo di nome o identificatore di filtro nel tuo stato, e quindi usarlo come chiave per cercare la funzione di filtro reale in un componente o selettore, in modo simile all'approccio suggerito per la gestione dei componenti di dialogo a http://stackoverflow.com/questions/35623656/how-can-i-display-a-modal-dialog-in-redux-that-performs-asynchronous-actions/. – markerikson

+1

Gli esempi potrebbero essere piacevoli – Green

6

composizione Reducer: De-comporre il riduttori in pezzi più piccoli in modo che un riduttore è abbastanza piccolo da affrontare con la struttura semplice di dati. per esempio. Nel tuo caso potresti avere: roomListReducerlistItemsReducerlistItemReducer. Quindi ad ogni riduttore, renderà molto più facile leggere la parte dello stato con cui si sta affrontando. Aiuta molto perché ognuno dei tuoi riduttori si occupa di piccoli dati che non ti devi preoccupare di cose come "dovrei copiare in profondità o copiare superficialmente".

Immutabile Io personalmente non uso immutable.js perché preferisco a che fare con gli oggetti semplici. e ci sono solo troppi codici da modificare per adottare una nuova API. Ma l'idea è, assicurati che i tuoi cambiamenti di stato avvengano sempre attraverso pure funzioni. Pertanto, puoi semplicemente scrivere le tue funzioni di supporto per fare ciò che vuoi, ma assicurati che siano testati accuratamente quando si tratta di oggetti complessi.

O semplicemente sufficiente, è sempre possibile copiare in profondità il proprio stato in ogni riduttore, e mormorare nella copia, quindi restituire la copia. Ma questo ovviamente non è il modo migliore.

+2

Documentazione combinedReducers: http://redux.js.org/docs/api/combineReducers.html –

+0

@StevenBayer mi è mancato qualcosa di importante? – xiaofan2406

+1

Con De-comporre i miei riduttori continuo a creare oggetti complessi, sono leggermente meno nidificati. Non è mancato nulla di importante, solo un link utile nel caso in cui qualcun altro riceva questo problema. –

Problemi correlati