2016-01-23 4 views
17

Perché gli oggetti in Redux dovrebbero essere immutabili? So che alcuni framework come Angular2 useranno onPush e possono sfruttare l'immutabilità per confrontare gli stati di vista per un rendering più veloce, ma mi chiedo se ci siano altri motivi, dal momento che Redux è agnostico per il framework e tuttavia cita all'interno dei propri documenti per usa l'immutabilità (indipendentemente dal framework).Perché gli oggetti in Redux dovrebbero essere immutabili?

Apprezzare qualsiasi feedback.

+1

Si rende le cose facile ragionare circa, e contribuisce a ti impedisce di cambiare accidentalmente lo stato al di fuori del modo in cui Redux lo fa. –

+3

tx per la risposta ... ma il suo tipo di vago .. So che è quello che dicono sempre .. cambiare un nome da A a B non rende più complesso o più difficile ragionare su ... – born2net

+4

Lasciami mettere in questo modo: se so che una struttura dati è Immutable, so che ci sono parti del codice che assolutamente non possono cambiarlo. Ciò rende molto più semplice testare il codice e trovare bug. –

risposta

12

Redux è una piccola libreria che rappresenta lo stato come oggetti (immutabili). E nuovi stati passando lo stato corrente attraverso pure funzioni per creare uno stato di oggetto/applicazione completamente nuovo.

Se i tuoi occhi non sono lucidi, non preoccuparti. Per riassumere, Redux non rappresenta cambiamenti nello stato della tua applicazione modificando gli oggetti (come faresti con i paradigmi orientati agli oggetti). Invece le modifiche di stato sono rappresentate come la differenza tra l'oggetto di input e l'oggetto di output (var output = reducer(input)). Se si muta o input o output, si annulla lo stato.

Per riassumere in un altro modo, l'immutabilità è un requisito di Redux perché Redux rappresenta lo stato dell'applicazione come "snapshot di oggetti congelati". Con queste istantanee discrete , è possibile salvare il proprio stato o stato inverso e in genere disporre di una maggiore "contabilità" per tutte le modifiche di stato.

Lo stato della tua app è solo modificato da una categoria di funzioni pure denominate riduttori. Riduttori hanno 2 importanti proprietà:

  1. Essi mai mutano, restituendo oggetti di nuova costruzione: ciò permette un ragionamento su ingresso + uscita senza effetti collaterali
  2. La loro firma è semprefunction name(state, action) {}, in modo che rende facile comporli:

assumere lo stato si presenta così:

var theState = { 
     _2ndLevel: { 
     count: 0 
     } 
    } 

Vogliamo incrementare il conteggio, quindi facciamo questi riduttori

const INCR_2ND_LEVEL_COUNT = 'incr2NdLevelCount'; 

function _2ndlevel (state, action) { 
    switch (action.type) { 
     case INCR_2ND_LEVEL_COUNT: 
      var newState = Objectd.assign({}, state); 
      newState.count++ 
      return newState; 
     } 
    } 

function topLevel (state, action) { 
    switch (action.type) { 
     case INCR_2ND_LEVEL_COUNT: 
      return Objectd.assign({}, {_2ndLevel: _2ndlevel(state._2ndlevel)}); 
    } 
} 

Nota l'uso di Objectd.assign({}, ...) per creare uno completamente nuovo oggetti in ogni riduttore:

Supponendo che abbiamo cablato Redux a questi riduttori, quindi se usiamo il sistema di eventi di Redux per innescare un cambio di stato ...

dispatch({type: INCR_2ND_LEVEL_COUNT}) 

... Redux chiamerà:

theNewState = topLevel(theState, action); 

NOTA: action da dispatch()

Ora theNewState è un oggetto completamente nuovo .

Nota: È possibile applicare immutabilità con a library (o new language features), o semplicemente stare attenti a non mutare nulla: D

Per uno sguardo più profondo, mi raccomando si checkout this video da Dan Abramov (il creatore). Dovrebbe rispondere a tutte le domande persistenti che hai.

+5

prima lasciami dire grazie per la risposta, io e te. Ma con quello, lascia che ti spieghi, sono molto consapevole di come funziona Redux, lo uso già, la mia domanda è di un pensiero più profondo. Pensaci, se hai cambiato un nome invece di sostituire l'intero oggetto che conteneva il nome, puoi ANCORA ottenere "istantanee di oggetti congelati". L'unica ragione (e questa potrebbe essere una buona ragione) è il confronto della velocità. Dal momento che potrebbe essere più veloce confrontare i nuovi oggetti e quelli modificati quando si blocca lo stato. Questa sarebbe l'unica ragione per cui potrei vedere ... tx Sean. – born2net

+1

Ahhh ok - whoops: P. Hmm, non capisco come si ottengono "istantanee di oggetti congelati" quando cambi un nome, come hai cambiato l'oggetto. Ma a prescindere, penso che tu sia sulla strada giusta.L'attenzione sull'immutabilità è dovuta al fatto che gli "economismi di elaborazione" che si verificano in una SPA tipica si prestano a uno stato di ricreazione di confronto degli oggetti poco profondi/stupidi. Immagina che non fosse un nome che hai modificato, ma un nome in una singola cella di 1000 righe in una tabella di rendering. Re-rendering della tabella quando _qualcosa_ cambia è più veloce di attraversare l'intero stato per scoprire _exactly what_ changed. –

+5

Non vedo come questo risponda alla domanda "Perché lo stato dovrebbe essere immutabile". Sì, spiega molto come farlo e si limita a ripetere le specifiche di Redux: "lo stato dovrebbe essere immutabile", ma nessuna descrizione/spiegazione della motivazione dietro di esso. Se ci fosse un motivo per cui gli stati delle applicazioni descrivono le transizioni (modifiche), si dovrebbe solo rendere ** Objectd.assign ({}, ...) ** prima e dopo qualsiasi chiamata di funzione pura. – Slav

7

Il seguente benefits of immutability sono menzionati nella documentazione Redux:

+0

In altre parole, ignorare la raccomandazione e lo stato 'mutante 'interferirà con la logica" dovrebbe aggiornare componente "? È possibile dire in che modo questo andrà male, cioè, il rendering avverrà sempre/mai/dipende? – bluenote10

+1

La risposta alla tua domanda non è banale. Dipende da come è strutturato il tuo stato, da quale proprietà profonda stai cambiando e se stai usando 'combineReducers' e/o' react-redux'. Puoi sicuramente sapere cosa accadrà con una più profonda comprensione di 'combina Reddito' e' reagisci-riduci '. In generale, quando non viene rilevato un cambiamento profondo a causa di un controllo superficiale, alcuni componenti nell'interfaccia utente non vengono aggiornati. Ma la linea di fondo è: non mutare lo stato_. È una cosa cattiva ™. –