2015-11-05 18 views
22

Quando si scrive un'applicazione react-redux, ho bisogno di mantenere sia l'applicazione e stato di interfaccia utente nella struttura di stato globale. Qual è l'approccio migliore per progettare la sua forma?Come separare interfaccia utente e lo stato dell'applicazione in Redux

Diciamo che ho una lista di todo elementi:

{ 
    items: [ 
    { id: 1, text: 'Chew bubblegum' }, 
    { id: 2, text: 'Kick ass' } 
    ] 
} 

Ora voglio lasciare che gli utenti di selezionare ed espandere le voci. Ci sono (almeno) due opzioni come modellare la forma dello stato:

{ 
    items: [ 
    { id: 1, text: 'Chew bubblegum', selected: true, expanded: false }, 
    { id: 2, text: 'Kick ass', selected: false, expanded: false } 
    ] 
} 

Ma questo è mescolare lo stato di interfaccia utente (selected e expanded) con lo stato dell'applicazione. Quando ho salvare l'elenco delle cose da fare al server, voglio salvare solo lo stato dell'applicazione, non lo stato di interfaccia utente (in applicazione del mondo reale, lo stato di interfaccia utente può contenere stato di finestre di dialogo modali, messaggi di errore, stato di convalida, ecc).

Un altro approccio è quello di mantenere un altro array per lo stato di interfaccia utente delle voci:

{ 
    items: [ 
    { id: 1, text: 'Chew bubblegum' }, 
    { id: 2, text: 'Kick ass' } 
    ], 
    itemsState: [ 
    { selected: true, expanded: false }, 
    { selected: false, expanded: false } 
    ] 
} 

poi si deve combinare questi due stati durante il rendering di un elemento. Posso immaginare che si può zip quei due array nella funzione connect per fare il rendering facile:

const TodoItem = ([item, itemState]) => ...; 
const TodoList = items => items.map(item => (<TodoItem item={item} />)); 

export default connect(state => _.zip(state.items, state.itemsState))(TodoList); 

Ma gli aggiornamenti di stato possano essere doloroso, perché items e itemsState devono essere tenuti in sincronia:

  1. Quando si rimuove un oggetto, è necessario rimuovere itemState corrispondente.
  2. Quando riordino articoli, itemsState deve essere prenotato anche.
  3. Quando l'elenco dei todo elementi viene aggiornato dal server, è necessario mantenere id nello stato di interfaccia utente e fare un po 'di riconciliazione.

C'è qualche altra opzione? Oppure esiste una libreria che aiuti a mantenere sincronizzati lo stato dell'app e lo stato dell'interfaccia utente?

+0

Hai trovato qualche soluzione/implementazione per questo? –

risposta

9

Un altro approccio ispirato normalizr:

{ 
    ids: [12,11], // registry and ordering 
    data: { 
     11: {text: 'Chew bubblegum'}, 
     12: {text: 'Kick ass'} 
    }, 
    ui: { 
     11: { selected: true, expanded: false }, 
     12: { selected: false, expanded: false } 
    } 
} 
0

Attualmente sto guardando questo me stesso per un progetto parallelo. Ho intenzione di avvicinarlo simile al metodo di Rick sopra. Il dato {} funge da fonte di verità e viene usato per spingere le modifiche dell'interfaccia utente locale in (che riflettono lo stato più corrente). È necessario unire i dati e ui insieme prima del rendering, e io stesso l'ho provato in alcuni punti. Devo dire che, per quanto riguarda la sincronizzazione, non dovrebbe essere troppo male. Fondamentalmente, ogni volta che salvi/recuperi i dati, stai aggiornando i dati {} e svuoti ui {} per prepararti al prossimo caso d'uso.

Problemi correlati