2015-12-28 23 views
58

Wiem, że Redux jest lepszą "implementacją" Flux, lub lepiej mówiąc, że jest to przeprojektowanie upraszczające rzeczy (zarządzanie stanem aplikacji).Redux & RxJS, wszelkie podobieństwa?

Wiele słyszałem o programowaniu reaktywnym (RxJS), ale nie nurkowałem, aby go jeszcze nauczyć.

Moje pytanie brzmi: czy istnieje jakieś skrzyżowanie (coś wspólnego) między tymi dwiema technologiami lub są one komplementarne? ... czy zupełnie inaczej?

Odpowiedz

95

Krótko mówiąc, są one bardzo różne biblioteki dla bardzo różnych celów, ale tak istnieją pewne podobieństwa niejasne.

Redux to narzędzie do zarządzania stanem w całej aplikacji. Zwykle jest używany jako architektura dla interfejsów użytkownika. Pomyśl o tym jako o alternatywie do (połowy) Angular.

RxJS jest reaktywną biblioteką programowania. Jest zwykle używany jako narzędzie do wykonywania asynchronicznych zadań w JavaScript. Pomyśl o tym jako o alternatywie do Obietnicy.


bierna jest paradygmat programowania (sposób działania i myślenia), gdzie zmiany danych są obserwowane z daleka. Dane nie są zmienione z odległości .

Oto przykład zmieniło od odległości:

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

model zostanie zmieniony od kontrolera.

Oto przykład obserwowane z daleka:

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

w rejestratorze, możemy obserwować zmiany danych, które zdarzają się w sklepie (z daleka), a następnie napisz do konsoli.


Redux używa paradygmatu Reactive tylko trochę: Sklep jest reaktywny. Nie ustawiasz jej treści z dystansu. Dlatego w Redux nie ma wersji store.set(). Sklep obserwuje działania z dystansu i sam się zmienia. Sklep pozwala innym obserwować dane z daleka.

RxJS również wykorzystuje paradygmat Reaktywny, ale zamiast być architekturą, daje podstawowe bloki konstrukcyjne, Observables, aby osiągnąć ten wzór "obserwując z odległości".

Podsumowując, bardzo różne rzeczy do różnych celów, ale podziel się pomysłami.

+1

, więc nie powinny być używane razem, prawda? – Oswaldo

+1

Nie, nie powinieneś używać ich razem. Ludzie emulowali Redux używając Rx. Szybkie Google znajdzie przykłady dla Ciebie. Jeśli chcesz używać Rx do swojego reaktywnego interfejsu użytkownika, sprawdź Cycle.js, framework Andre. Używam go ostatnio i jest fantastyczny. API bardzo się ostatnio zmieniło, ale uważam, że w końcu zaczyna zamrozić jego część. –

+9

według [oficjalne dokumenty redux] (http://redux.js.org/docs/introduction/PriorArt.html), "Działają wspaniale razem". – galki

18

Są to bardzo różne rzeczy.

RxJS może być używany do programowania reaktywnego i jest bardzo dokładną biblioteką z ponad 250 operatorami.

Redux jest taki, jak opisano w repozytorium github "Redux jest przewidywalnym kontenerem stanu dla aplikacji JavaScript".

Redux to tylko narzędzie do obsługi stanu w aplikacjach. Ale w porównaniu możesz zbudować pełną aplikację w RxJS.

Nadzieja to pomaga :)

+2

Twoja odpowiedź też jest dobra @cmdv. Nie widziałem tego, kiedy pisałem moje. –

+3

okrzyki, to nie jest aż tak obojętne :) @ AndréStaltz – cmdv

1

Chciałem tylko dodać pewne pragmatyczne różnice od kiedy stworzyłem kod RxJS inspirowany Redux.

Zmapowałem każdy typ akcji na instancję Temat. Każdy element stanowy będzie miał obiekt, który jest następnie zamapowany do funkcji reduktora. Wszystkie strumienie reduktora są połączone z merge, a następnie scan wyprowadza stan. Domyślną wartością jest startWith tuż przed scan. Użyłem publishReplay(1) dla stanów, ale mogę go później usunąć.

Funkcja reagowania czystego renderowania będzie dotyczyć tylko miejsca, w którym tworzy się dane zdarzeń, wysyłając wszystkich producentów/podmioty.

Jeśli masz komponenty potomne, musisz opisać, jak te stany są połączone w twoje. combineLatest może być dobrym punktem wyjścia do tego.

Wybitne różnice w realizacji:

  • Nie middleware, tylko rxjs operatorów. Myślę, że to jest największa siła i słabość. Nadal możesz pożyczyć koncepcje, ale trudno mi uzyskać pomoc od takich społeczności siostrzanych jak redux i cycle.js, ponieważ jest to kolejne niestandardowe rozwiązanie. Dlatego w tym tekście muszę napisać "ja" zamiast "my".

  • Brak przełącznika/przypadku lub ciągów znaków dla typów czynności. Masz bardziej dynamiczny sposób oddzielania działań.

  • rxjs może być używany jako narzędzie w innym miejscu i nie jest zawarty w zarządzaniu stanem.

  • Mniejsza liczba producentów niż typy czynności (?). Nie jestem tego pewien, ale możesz mieć wiele reakcji w komponentach nadrzędnych, które nasłuchują komponentów potomnych. Oznacza to mniej imperatywny kod i mniej złożoności.

  • Jesteś właścicielem rozwiązania. Żadne ramy nie są potrzebne. Dobry i zły. W końcu będziesz pisał własne ramy.

  • To znacznie więcej fraktali i można łatwo subskrybować zmiany z pod-drzewa lub wielu części drzewa stanu aplikacji.

    • Zgadnij, jak łatwo jest robić eposy, jak redux-obseravble? Naprawdę proste.

Ja również pracuje na znacznie większe korzyści, gdzie elementy potomne są opisane jako strumienie. Oznacza to, że nie musimy dopasowywać stanu nadrzędnego i podrzędnego w reduktorach, ponieważ możemy po prostu ("po prostu") rekurencyjnie łączyć stany w oparciu o strukturę komponentów.

Też myślę o przeskakiwaniu reaguję i idę ze snabbdomem albo czymś innym dopóki React lepiej nie obsługuje stanów reaktywnych. Dlaczego mielibyśmy budować nasze państwo w górę, aby ponownie je rozbić za pomocą rekwizytów? Tak więc postaram się stworzyć wersję 2 tego wzorca z Snabbdom.

Oto bardziej zaawansowany, ale mały fragment, w którym plik state.ts tworzy strumień stanu.Jest to stan składnika formularza ajax, który pobiera obiekt pól (dane wejściowe) z regułami sprawdzania poprawności i stylami css. W tym pliku używamy tylko nazw pól (kluczy obiektów), aby połączyć wszystkie stany dzieci w stan formularza.

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

Podczas gdy kod nie może powiedzieć dużo w izolacji, to pokazuje, jak można zbudować stan w górę i jak można tworzyć dynamiczne wydarzenia z łatwością. Cena do zapłaty jest taka, że ​​musisz zrozumieć inny styl kodu. I uwielbiam płacić tę cenę.

+0

Rok później, po prostu znalazłeś odpowiedź i myślisz, że wciąż jest ważna! Zrobiłem coś podobnego i zgadzam się ze wszystkimi punktami. Ale pytanie w każdym razie: czy nadal myślisz tak samo dzisiaj, czy też odszedłeś od tego czasu? – Xceno

+1

Muszę zrewidować krytykę dotyczącą przełącznika/obudowy i typów działań w Redux. Nadal wykonuję kod w ten sam sposób, ale próbuję pracować, jak uzyskać działające po stronie serwera. Jeśli chodzi o kod React, udało mi się zrobić małe narzędzie, które pomaga w tworzeniu reduktorów/aktualizacji. Więc nadal robię to samo, ale trochę bardziej dopracowane. Największa zmiana polega na tym, że każdy węzeł liścia subskrybuje strumień na componentDidMount i rezygnuje z subskrypcji componentDidUnmount. Chcę uzyskać również warstwę usługi reaktywnej, która działa na interfejsie użytkownika i zapleczu. Robiąc postępy tam. –