2015-12-28 20 views
58

So che Redux è una migliore "implementazione" di Flux, o meglio dire che è una riprogettazione per semplificare le cose (gestione dello stato dell'applicazione).Redux & RxJS, eventuali somiglianze?

Ho sentito parlare molto della programmazione reattiva (RxJS), ma non mi sono ancora immerso per impararlo.

Quindi la mia domanda è: c'è qualche intersezione (qualcosa in comune) tra queste due tecnologie o sono complementari? ... o totalmente diverso?

risposta

95

In breve, essi sono molto diverse librerie per scopi molto diversi, ma sì, ci sono alcune somiglianze vaghe.

Redux è uno strumento per la gestione dello stato in tutta l'applicazione. Di solito è usato come architettura per le interfacce utente. Pensala come alternativa a (metà di) Angolare.

RxJS è una libreria di programmazione reattiva. Solitamente viene utilizzato come strumento per eseguire attività asincrone in JavaScript. Pensala come alternativa alle Promesse.


programmazione reattiva è un paradigma (modo di lavorare e di pensare) in cui i cambiamenti di dati sono osservato da una distanza. I dati non sono modificati da una distanza.

Ecco un esempio di cambiato da una distanza:

// In the controller.js file 
model.set('name', 'George'); 

Il modello viene modificato dal controller.

Ecco un esempio di osservato da una distanza:

// logger.js 
store.subscribe(function (data) { 
    console.log(data); 
}); 

Nel Logger, osserviamo le modifiche dei dati che avvengono in deposito (da lontano), e scriviamo alla console.


Redux utilizza il paradigma Reattivo solo un po ': lo Store è reattivo. Non si imposta il suo contenuto da una distanza. Ecco perché non c'è store.set() in Redux. Lo Store osserva le azioni da una certa distanza e cambia se stesso. E lo Store consente ad altri di osservare i suoi dati da lontano.

RxJS utilizza anche il paradigma Reactive, ma invece di essere un'architettura, fornisce elementi di base, Observable, per eseguire questo schema di "osservazione a distanza".

Per concludere, cose molto diverse per scopi diversi, ma condividere alcune idee.

+1

quindi non dovrebbero essere usati insieme, giusto? – Oswaldo

+1

No, non dovresti usarli insieme. Le persone hanno emulato Redux usando Rx. Un rapido Google troverà esempi per te. Se si desidera utilizzare Rx per l'interfaccia utente reattiva, verificare Cycle.js, quadro di Andre. L'ho usato ultimamente ed è fantastico. L'API sta cambiando molto recentemente, ma credo che stia finalmente iniziando a congelare parti di esso. –

+9

secondo [documenti redux ufficiali] (http://redux.js.org/docs/introduction/PriorArt.html), "Lavorano alla grande insieme." – galki

18

Sono cose molto diverse.

RxJS può essere utilizzato per eseguire la programmazione reattiva ed è una libreria molto completa con oltre 250 operatori.

E Redux è come descritto sul repository github "Redux è un contenitore di stato prevedibile per le app JavaScript".

Redux è solo uno strumento per gestire lo stato nelle app. Ma in confronto potresti creare un'app completa solo in RxJS.

Spero che questo aiuti :)

+2

Anche la risposta è buona @cmdv. Non l'ho visto mentre stavo scrivendo il mio. –

+3

evviva, non è altrettanto così però :) @ AndréStaltz – cmdv

1

Volevo solo aggiungere alcune differenze pragmatiche da quando facevo il codice RxJS ispirato a Redux.

Ho mappato ogni tipo di azione a un'istanza Subject. Ogni componente stateful avrà un oggetto che viene quindi mappato in una funzione di riduzione. Tutti i flussi del riduttore sono combinati con merge e quindi lo stato è scan. Il valore predefinito è impostato con startWith poco prima dello scan. Ho usato publishReplay(1) per gli stati, ma potrei rimuoverlo in seguito.

La funzione di reazione pura render sarà solo posizionare dove si producono i dati degli eventi inviando tutti i produttori/soggetti.

Se si dispone di componenti figlio, è necessario descrivere in che modo tali stati sono combinati nel proprio. combineLatest potrebbe essere un buon punto di partenza per questo.

differenze notevoli di attuazione:

  • No middleware, basta rxjs operatori. Penso che questo sia il più grande potere e debolezza. È ancora possibile prendere in prestito concetti, ma trovo difficile ottenere aiuto da comunità sorelle come redux e cycle.js poiché è un'altra soluzione personalizzata. Ecco perché ho bisogno di scrivere "io" invece di "noi" in questo testo.

  • Nessun interruttore/caso o stringhe per i tipi di azione. Hai un modo più dinamico di separare le azioni.

  • rxjs può essere utilizzato come strumento altrove e non è contenuto nella gestione dello stato.

  • Minore numero di produttori rispetto ai tipi di azione (?). Non ne sono sicuro, ma puoi avere molte reazioni nei componenti padre che ascoltano i componenti figlio. Ciò significa meno codice imperativo e meno complessità.

  • Sei il proprietario della soluzione. Nessun quadro necessario. Buono e cattivo. Finirai per scrivere comunque il tuo framework.

  • È molto più frattale e puoi facilmente iscriverti alle modifiche da un sottoalbero o da più parti dell'albero di stato dell'app.

    • Indovina com'è facile fare le epiche come fa redux-obseravble? Davvero facile.

Sto anche lavorando su molto più grandi benefici in cui i componenti del bambino sono descritti come flussi. Ciò significa che non dobbiamo integrare lo stato genitore e figlio nei riduttori, poiché possiamo semplicemente ("solo") combinare ricorsivamente gli stati in base alla struttura dei componenti.

Penso anche a saltare reagire e andare con snub o qualcos'altro fino a quando React gestisce meglio gli stati reattivi. Perché dovremmo costruire il nostro stato verso l'alto solo per abbatterlo di nuovo con gli oggetti di scena? Quindi proverò a creare una versione 2 di questo modello con Snabbdom.

Ecco uno snippet più avanzato ma piccolo in cui il file state.ts crea il flusso di stato.Questo è lo stato del componente ajax che ottiene un oggetto di campi (input) con regole di validazione e stili css. In questo file usiamo solo i nomi dei campi (chiavi oggetto) per combinare tutti gli stati dei bambini nello stato del modulo.

export default function create({ 
    Observable, 
    ajaxInputs 
}) { 
    const fieldStreams = Object.keys(ajaxInputs) 
    .map(function onMap(fieldName) { 
    return ajaxInputs[fieldName].state.stream 
    .map(function onMap(stateData) { 
     return {stateData, fieldName} 
    }) 
    }) 

    const stateStream = Observable.combineLatest(...fieldStreams) 
    .map(function onMap(fieldStreamDataArray) { 
    return fieldStreamDataArray.reduce(function onReduce(acc, fieldStreamData) { 
    acc[fieldStreamData.fieldName] = fieldStreamData.stateData 
    return acc 
    }, {}) 
    }) 

    return { 
    stream: stateStream 
    } 
} 

Mentre il codice potrebbe non dire molto in modo isolato, mostra come si può costruire di stato verso l'alto, e come si può produrre eventi dinamici con facilità. Il prezzo da pagare è che devi capire uno stile diverso di codice. E amo pagare quel prezzo.

+0

è un anno dopo, ho solo trova la tua risposta e pensa che sia ancora valida! Ho fatto qualcosa di simile e sono d'accordo con tutti i tuoi punti. Ma una domanda comunque: credi ancora la stessa cosa oggi, o ti sei trasferito da allora? – Xceno

+1

Ho bisogno di rivedere la critica su switch/case e tipi di azione in Redux. Continuo a scrivere codice allo stesso modo, ma sto cercando di capire come farlo funzionare sul lato server. Quando si tratta di codice React, sono riuscito a fare un piccolo util che aiuta a creare i riduttori/updaters. Quindi sto ancora facendo la stessa cosa, ma un po 'più lucido. Il più grande cambiamento è che ho lasciato che ogni nodo foglia si iscriva allo stream su componentDidMount e annulli l'iscrizione a componentDidUnmount. Desidero ottenere anche un livello di servizio reattivo che funzioni sul frontend e sul backend. Fare progressi lì. –