Redux e RxJS, qualche somiglianza?


113

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

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

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

Risposte:


185

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

Redux è uno strumento per la gestione dello stato in tutta l'applicazione. Di solito viene utilizzato come architettura per le interfacce utente. Pensalo come un'alternativa a (metà di) Angular.

RxJS è una libreria di programmazione reattiva. Di solito viene utilizzato come strumento per eseguire attività asincrone in JavaScript. Consideralo un'alternativa alle promesse.


La programmazione reattiva è un paradigma (modo di lavorare e pensare) in cui i cambiamenti dei dati vengono osservati a distanza . I dati non vengono modificati a distanza .

Ecco un esempio di modifica a distanza :

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

Il Modello viene modificato dal Controller.

Ecco un esempio di osservato da lontano :

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

Nel Logger, osserviamo le modifiche ai dati che avvengono in Store (a distanza) e scriviamo sulla console.


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

RxJS utilizza anche il paradigma Reattivo, ma invece di essere un'architettura, ti fornisce elementi costitutivi di base, osservabili , per realizzare questo modello di "osservazione a distanza".

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


4
No, non dovresti usarli insieme. Le persone hanno emulato Redux usando Rx. Una rapida Google troverà esempi per te. Se vuoi usare Rx per la tua interfaccia utente reattiva, controlla Cycle.js, il framework di Andre. L'ho usato ultimamente ed è fantastico. L'API è cambiata molto recentemente, ma credo che finalmente stia iniziando a congelarne alcune parti.
Joel Dentici

17
secondo i documenti redux ufficiali , "Lavorano alla grande insieme".
galki

12
Funzionano benissimo insieme! Esiste un middleware Redux che ti dà l'opportunità di utilizzare RxJS e Observables per le azioni Redux. github.com/redux-observable/redux-observable Inoltre ho scritto un post sul blog su How To: robinwieruch.de/redux-observable-rxjs
Robin Wieruch

1
Il paradigma Redux ha contribuito a rendere la base di codice del mio progetto Android più reattiva. I nostri flussi di dati provenienti da pulsanti e altri campi per aggiornare uno stato, insieme a RxJava, hanno potenziato la nostra leggibilità e prestazioni. Le biblioteche vanno decisamente bene insieme ei loro vantaggi sono indipendenti dalla lingua.
Kenny Worden

Funzionano benissimo insieme, ma in pratica Reactive può fare per te quello che farebbe Redux: sincronizzare lo stato dei tuoi componenti con il modello, quindi spesso non ha molto senso usarli entrambi
Filip Sobczak

32

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 nel 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 con RxJS.

Spero che questo ti aiuti :)


3
Anche la tua risposta è buona @cmdv. Non l'ho visto mentre scrivevo il mio.
André Staltz

4

Redux è solo una libreria di gestione dello stato che viene fornita con standard ben definiti per le operazioni di aggiornamento. Se ti attieni agli standard, puoi mantenere il flusso di dati sano e facile da ragionare. Offre anche la possibilità di migliorare il flusso di dati con middleware e potenziatori di negozi.

RxJS è un toolkit per la programmazione reattiva. Puoi effettivamente pensare a ogni cosa che accade nella tua app come a uno stream. RxJS offre un set di strumenti molto ricco per gestire questi flussi.

Dove intercetta RxJS e Redux? In redux aggiorni il tuo stato con azioni e ovviamente queste azioni possono essere trattate come flussi. Utilizzando un middleware come Redux-Observable (non è necessario) è possibile implementare la cosiddetta "logica di business" in modo reattivo. Un'altra cosa è che puoi creare un osservabile dal tuo negozio redux che a volte potrebbe essere più semplice rispetto all'utilizzo di un potenziatore.


2

Per dirla in breve:

Redux: libreria ispirata a Flux utilizzata per la gestione dello stato .

RxJS: È un'altra libreria Javascript basata sulla filosofia di programmazione reattiva, utilizzata per gestire "Stream" (osservabili, ecc.) [Leggi la programmazione reattiva per comprendere i concetti di Stream].


1

Volevo solo aggiungere alcune differenze pragmatiche rispetto a quando ho creato il codice RxJS ispirato a Redux.

Ho mappato ogni tipo di azione su un'istanza del Soggetto. Ogni componente stateful avrà un Soggetto che viene quindi mappato in una funzione di riduzione. Tutti i flussi del riduttore vengono combinati con mergee quindi scanemettono lo stato. Il valore predefinito è impostato con startWithappena prima di scan. L'ho usato publishReplay(1)per gli stati, ma potrei rimuoverlo in seguito.

La funzione di rendering puro di reazione sarà solo il luogo in cui si producono i dati dell'evento inviando tutti i produttori / Soggetti.

Se hai componenti figlio, devi descrivere come questi stati sono combinati nel tuo. combineLatestpotrebbe essere un buon punto di partenza per questo.

Notevoli differenze nell'implementazione:

  • Nessun middleware, solo operatori rxjs. Penso che questo sia il più grande potere e debolezza. Puoi ancora prendere in prestito concetti, ma trovo difficile ottenere aiuto da comunità sorelle come redux e cycle.js poiché è ancora 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.

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

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

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

    • Indovina quanto è facile fare epiche come il redux-obseravble? Davvero facile.

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

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

Ecco uno snippet più avanzato ma piccolo in cui il file state.ts costruisce il flusso di stato. Questo è lo stato del componente ajax-form che ottiene un oggetto di campi (input) con regole di convalida e stili CSS. In questo file usiamo semplicemente i nomi dei campi (chiavi degli oggetti) per combinare tutti gli stati dei bambini nello stato della forma.

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
  }
}

Anche se il codice potrebbe non dire molto da solo, mostra come è possibile creare uno stato verso l'alto e come produrre eventi dinamici con facilità. Il prezzo da pagare è che devi capire uno stile di codice diverso. E mi piace pagare quel prezzo.


È passato un anno, ho appena trovato la tua risposta e penso che sia ancora valida! Ho fatto qualcosa di simile e sono d'accordo con tutti i tuoi punti. Ma una domanda comunque: pensi ancora lo stesso oggi o sei andato avanti da allora?
Xceno

1
Ho bisogno di rivedere la critica su switch / case e tipi di azione in Redux. Faccio ancora il codice allo stesso modo, ma cerco di capire come farlo funzionare sul lato server. Quando si tratta di codice React, sono riuscito a fare una piccola utility che aiuta a creare i riduttori / aggiornamenti. Quindi sto ancora facendo la stessa cosa, ma un po 'più lucido. Il cambiamento più grande è che ho permesso a ogni nodo foglia di iscriversi al flusso su componentDidMount e annullare l'iscrizione su componentDidUnmount. Voglio anche ottenere un livello di servizio reattivo che funzioni sul frontend e sul backend. Fare progressi lì.
Marcus Rådell
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.