2015-04-14 17 views
20

Ho creato la mia prima applicazione React con negozi con stato nel modo "normale" e ora sto cercando di utilizzare uno stato globale immutabile come quello utilizzato nello starterkit .Quali sono gli svantaggi dell'utilizzo dello stato immutabile in React?

  • Lo stato di tutti i negozi è tenuti insieme in un'unica struttura di dati immutabili
  • componenti hanno statali ma accesso ai dati in loro render() sulla base di una funzione di memorizzazione getter
  • negozi sono anche stateless ma mutare lo stato dell'applicazione globale per il loro dominio utilizzando un cursore.
  • Il componente di livello superiore dell'app ascolta le modifiche di stato e esegue nuovamente il rendering dell'intero albero dei componenti.
  • I componenti sono implementati come "puri", ovvero utilizzano shouldComponentUpdate per calcolare in modo efficiente che possono essere saltati nel re-rendering.

Semplifica la struttura dell'applicazione in alcuni modi:

  • componenti non ascoltano i negozi e anche non copiare memorizzare i dati al loro stato locale. Prendono semplicemente il loro stato di negozio su ogni rendering.
  • Lo stato globale è sempre un'istantanea dell'intera applicazione, rendendo più facile il debug e l'aggiunta di funzionalità come Annulla banale.
  • Lo stato globale sembra semplificare il rendering isomorfo.

Ho letto solo cose positive sull'utilizzo di dati immutabili con React, e si raccomanda di evitare lo stato nei componenti, quindi mi chiedo se ci sono degli svantaggi. Ho pensato che ci fosse perché altrimenti non vedo perché non è raccomandato come il modo per strutturare le app React.

L'immutabilità è nuova per me, quindi ci sono delle avvertenze che dovrei essere a conoscenza se inizi a utilizzare questo approccio in un'app complessa del mondo reale?

L'unica cosa minore che posso pensare è l'uso di forceUpdate() come Este lo sta usando, come ho letto che è una funzione sincrona. Per esempio, Morearty sembra rimandare gli aggiornamenti al prossimo fotogramma dell'animazione per ridimensionarli, ma ritengo che questo sia un dettaglio/ottimizzazione dell'implementazione e non alcuni aspetti negativi dell'approccio immutabile allo stato unico.

+0

Probabilmente più creazione di oggetto (poiché le funzioni di manipolazione dati restituiscono copie), e quindi maggiore utilizzo di memoria e tasso di abbandono del GC. – joews

+0

@joews non necessariamente. I progetti che utilizzano strutture dati persistenti, come [mori] (http://swannodette.github.io/mori/), non comportano costi in questo modo. –

+0

@DavinTryon Sono d'accordo, quindi "probabilmente" - accadrà a meno che non si adottino misure per evitarlo. – joews

risposta

12

La risposta accettata, non si avvicina nemmeno a descrivere le problematiche esistenti ...

  1. documentazione. Alcune delle domande/rilasioni più votate in SO riguardano argomenti banali come l'aggiornamento di voci di elenchi annidati perché la documentazione è più orientata verso un pubblico familiare con la programmazione funzionale, che lo rende meno accessibile al resto.
  2. Non è banale separare la conoscenza della gerarchia del modello dai componenti. Odio fare un this.state.getIn("[parent, child, index]") in un componente perché aumenta la possibilità che un cambio di modello interrompa il codice del componente. Questo è prevenibile dall'estensibilità (di più su quella di seguito) o dai metodi di supporto, ma sicuramente si perde la semplicità dei membri di JS.
  3. Una sfida significativa che ho dovuto affrontare era la possibilità di serializzare e de-serializzare lo stato. Il metodo fromJS supporta i revival personalizzati ma sono una pita e richiedono un'attenta verifica e manutenzione.
  4. Il tipo di record è gravemente stordito da una debilitazione denominata annidamento. Questo è triste perché consente un'estensibilità più semplice (in termini relativi), ma incoraggia solo una gerarchia a livello singolo. Non è possibile creare facilmente record annidati da JSON. Questo rende difficile mescolarli con un uso immutabile normale da JS a meno che non si utilizzino i revival pita sopra menzionati. E ho detto quanto sia triste, dato che Records espone le proprietà del modello come membri di prima classe, assicurando l'integrità del modello e le impostazioni predefinite.
  5. E poi c'è estensibilità. Prova ad aggiungere helper attorno ai tuoi modelli di dati immutabili alla dipendenza astratta della gerarchia dei modelli nei tuoi componenti e sei pronto per una corsa ad ostacoli notevole. La serializzazione diventa una dura battaglia per il divorzio. Avresti bisogno di gironzolare con i rivoltosi, se i Record sono nel mix piangeranno fallo e così via. Un meccanismo di estensibilità più semplice farebbe molto per rendere il mio codice dei componenti più pulito.
  6. Nessuna best practice documentata. Anche se questo va bene con # 1, devo ancora dire che la mancanza di una buona documentazione impedisce di scegliere il modo migliore di fare qualcosa. Non sono sicuro se dovrei scegliere di utilizzare un programma di aggiornamento, o perOne o setIn (e così via) per aggiornare una struttura immutabile. I metodi non si confrontano a vicenda abbastanza da farti sapere quali sono le alternative disponibili.
+1

Grazie. Lo accetterò come risposta dato che fornisce ulteriori informazioni oltre all'ovvio. –

+1

La maggior parte di questi argomenti sembra essere un argomento contro l'uso di Immutable.js. È possibile scrivere Javascript normali e fare comunque attenzione a non mutare alcun oggetto, ottenendo così l'immutabilità pratica. – efdee

+1

Hai ragione, tuttavia la domanda è stata contrassegnata con ImmutableJS e la discussione si è concentrata principalmente su di esso. – hazardous

6

Un vantaggio del passaggio di dati tramite oggetti di scena è che è possibile utilizzare shouldComponentUpdate per ulteriori aggiornamenti. Se si presuppone che i dati provengano sempre dal genitore (ad esempio tramite oggetti di scena), è possibile impedire in modo efficace una grande porzione dell'albero dei componenti di dover eseguire il rerender. I valori immutabili rendono questo molto piacevole, in quanto è possibile fare controlli di uguaglianza di riferimento in shouldComponentUpdate relativamente alti nella gerarchia dei componenti.

L'unico altro svantaggio che ho trovato usando dati immutabili con React è che gli strumenti di sviluppo di React non funzionano molto bene con loro (mostrano la struttura dei dati sottostante dei valori immutabili invece di un valore JS-friendly).

+0

I vantaggi che conosco, ecco perché voglio usarlo :) Is ispezionare i dati immutabili anche un problema per i componenti più in basso nella gerarchia? Voglio dire, se i dati vengono trasmessi come oggetti di scena non si visualizzeranno in forma più leggibile lì? –

+0

@ 0x80 Sì, se si convertono valori immutabili in valori JS semplici e li si passa sopra, saranno più leggibili, ma si perderà la facilità di uguaglianza di riferimento in 'shouldComponentUpdate' più in basso nell'albero. Potrebbe essere un buon compromesso. –

+1

Grazie. Speriamo che qualcuno trovi una soluzione per mostrare bene i valori negli strumenti di sviluppo React un giorno. –

3

So che la risposta è già stata accettata, ma trovo lo svantaggio principale di passare oggetti JavaScript non chiari nel codice componente, ovvero non è possibile utilizzare il normale JavaScript property accessors durante la lettura dei valori dagli oggetti Immutable passati in via props. Invece devi use Immutable.js' read API. Questo è un importante compromesso. Non puoi mantenere il tuo uso di Immutable.js conteneva dove appartiene, nel negozio; ora è fuoriuscito da solo nell'intera applicazione. Questo è un dolore che potresti provare quando Immutable.js viene sostituito dalla successiva libreria di Immutability con la propria API o che è in grado di utilizzare gli accessor di proprietà native. Inoltre, il codice di terze parti si aspetta quasi certamente semplici vecchi oggetti JavaScript, quindi è necessario convertire gli oggetti immutabili prima di passarli. Se hai intenzione di introdurre Immutable.js in un'applicazione esistente, diventerà poco chiaro nel tuo codice componente che props è immutabile e che sono oggetto JS, a meno che tu non sia molto disciplinato e crei uno schema di denominazione o qualche altro metodo che sei coerente quando passi oggetti lungo la catena di rendering.

+0

Dai un'occhiata a Records. Consentono alcune somiglianze con un oggetto JS più tradizionale in termini di esposizione dei membri di prima classe ed estensibilità. Ma hanno le loro insicurezze, vedi la mia risposta qui sotto. – hazardous

Problemi correlati