2015-10-29 5 views
53

Così ho iniziato a imparare React una settimana fa e ho inevitabilmente raggiunto il problema dello stato e di come i componenti dovrebbero comunicare con il resto dell'app. Ho cercato in giro e Redux sembra essere il sapore del mese. Ho letto tutta la documentazione e penso che sia davvero un'idea piuttosto rivoluzionaria. Ecco i miei pensieri su di esso:Non è Redux solo stato globale glorificato?

Lo stato è generalmente accettato di essere piuttosto malvagio e una grande fonte di bug nella programmazione. Invece di disperdere tutto nella tua app, Redux dice perché non solo concentrarti tutto su un albero di stato globale che devi emettere azioni da modificare? Sembra interessante. Tutti i programmi hanno bisogno di stato, quindi mettiamolo in uno spazio impuro e modificalo solo da lì, quindi i bug sono facili da rintracciare. Quindi possiamo anche legalmente dichiarare pezzi di stato singoli ai componenti React e farli ridisegnare automaticamente e tutto è bello.

Tuttavia, ho due domande su questo intero progetto. Per uno, perché l'albero statale deve essere immutabile? Dite che non mi interessa il debug del viaggio nel tempo, il ricaricamento a caldo e ho già implementato l'annullamento/ripristino nella mia app. Sembra proprio così scomodo dover fare questo:

case COMPLETE_TODO: 
    return [ 
     ...state.slice(0, action.index), 
     Object.assign({}, state[action.index], { 
     completed: true 
     }), 
     ...state.slice(action.index + 1) 
    ]; 

Invece di questo:

case COMPLETE_TODO: 
    state[action.index].completed = true; 

Per non parlare sto facendo una lavagna on-line solo per imparare e ogni cambiamento di stato potrebbe essere semplice come aggiungere un tratto di pennello all'elenco dei comandi. Dopo un po '(centinaia di pennellate) la duplicazione di questo intero array potrebbe iniziare a diventare estremamente costosa e dispendiosa in termini di tempo.

Sto bene con un albero di stato globale che è indipendente dall'interfaccia utente che è mutato tramite azioni, ma ha davvero bisogno di essere immutabile? Cosa c'è di sbagliato in una semplice implementazione come questa (bozza molto approssimativa, scritta in 1 minuto)?

var store = { items: [] }; 

export function getState() { 
    return store; 
} 

export function addTodo(text) { 
    store.items.push({ "text": text, "completed", false}); 
} 

export function completeTodo(index) { 
    store.items[index].completed = true; 
} 

È ancora un albero di stato globale mutato tramite azioni emesse ma estremamente semplice ed efficiente.

+1

"Per uno, perché l'albero di stato deve essere immutabile?" --- allora devi fornire un algoritmo per determinare se i dati sono cambiati. Non è possibile implementarlo per una struttura di dati arbitraria (se è mutabile). Prendi 'immutablejs' e usa' return state.setIn ([action.index, 'completed'], true); 'per ridurre il boilerplate. – zerkms

+0

PS: 'return state.map (i => i.index == action.index? {... i, completato: true}: i);' – zerkms

risposta

32

Non è Redux solo stato globale glorificato?

Ovviamente lo è. Ma lo stesso vale per ogni database che tu abbia mai usato. È meglio trattare Redux come un database in memoria, dal quale i tuoi componenti possono dipendere in modo reattivo.

L'immutabilità consente di verificare se un sottoalbero è stato modificato in modo molto efficiente perché semplifica il controllo dell'identità.

Sì, la tua implementazione è efficiente, ma l'intera dom virtuale dovrà essere ripetuta ogni volta che l'albero viene manipolato in qualche modo.

Se si utilizza React, alla fine eseguirà una diff contro il dom effettivo ed eseguirà manipolazioni minime ottimizzate per il lotto, ma il re-rendering completo dall'alto verso il basso è ancora inefficiente.

Per un albero immutabile, i componenti stateless devono solo verificare se il sottoalbero o gli sottostanti dipendono, differiscono in identità rispetto ai valori precedenti e, in tal caso, il rendering può essere evitato completamente.

+2

Non si tratta di un po 'di ottimizzazione prematura? Inoltre, come facciamo a sapere che il costo di duplicare costantemente oggetti immutabili è inferiore al re-rendering del DOM (anche se il DOM virtuale di React non attenua pesantemente questo costo?) –

+3

Bene, le librerie GUI questo tipo di ottimizzazione per un lungo periodo (Fare riferimento a: http://bitquabit.com/post/the-more-things-change/) Inoltre, la gestione di una struttura dati immutabile non è così costosa come si potrebbe pensare - ad esempio se un nodo viene modificato, solo una singola catena di i genitori devono fare una catena - il resto dei nodi rimane inalterato. Quindi non stiamo duplicando la * intera * struttura dati per ogni azione - riutilizziamo i sottocomponenti che non sono stati modificati per costruire una nuova struttura dati. – lorefnon

+0

E il mio array di pennellate? Esiste un modo immutabile ed efficiente per duplicare questa serie di centinaia di elementi quando si aggiunge solo un elemento alla fine dell'array? –