Dlaczego warto używać Redux nad Facebook Flux?

Przeczytałem tę odpowiedź, redukując boilerplate , spojrzałem na kilka przykładów GitHub i nawet wypróbowałem trochę redux (aplikacje todo).

Jak rozumiem, oficjalne motywacje redux doc zapewniają plusy w porównaniu z tradycyjnymi architekturami MVC. Ale nie daje odpowiedzi na pytanie:

Dlaczego warto używać Redux nad Facebook Flux?

czy to tylko kwestia stylów programowania: funkcjonalny vs niefunkcjonalny? Lub pytanie jest w umiejętności / dev-narzędzia, które wynikają z podejścia redux? Może skalowanie? Albo testy?

Czy mam rację, jeśli mówię, że redux jest strumieniem dla ludzi, którzy pochodzą z języków funkcyjnych?

Aby odpowiedzieć na to pytanie, możesz porównać złożoność implementacji punktów motywacyjnych redux na flux vs redux.

Oto punkty motywacji z official redux Doc motivations :

  1. Obsługa optymistycznych aktualizacji (jak I zrozum, to nie zależy od piątego punktu. Czy trudno jest to wdrożyć w Facebook flux?)
  2. Rendering na serwerze (facebook flux również może to zrobić. Jakieś korzyści w porównaniu do redux?)
  3. pobieranie danych przed wykonaniem przejścia trasy (dlaczego nie można tego osiągnąć w Facebook flux? Jakie są korzyści?)
  4. Hot reload ( jest to możliwe dzięki React Hot Reload . Po co nam redux?)
  5. Cofnij / Ponów funkcjonalność
  6. Jakieś inne punkty? Jak uporczywe Państwo...
Author: rahul singh Chauhan, 2015-09-08

7 answers

Redux author here!

Redux nie różni się od Flux. Ogólnie ma tę samą architekturę, ale Redux jest w stanie wyciąć kilka narożników złożoności za pomocą kompozycji funkcjonalnej, gdzie Flux wykorzystuje rejestrację wywołania zwrotnego.

Nie ma zasadniczej różnicy w Reduxie, ale uważam, że sprawia, że pewne abstrakcje są łatwiejsze, a przynajmniej możliwe do zaimplementowania, które byłyby trudne lub niemożliwe do zaimplementowania w Strumieniu.

Skład Reduktora

Weź, dla przykład: paginacja. Mój przykład Flux + react router obsługuje stronicowanie, ale kod do tego jest okropny. Jednym z powodów, dla których jest to okropne, jest to, że Flux sprawia, że nienaturalne jest ponowne wykorzystanie funkcjonalności w sklepach. Jeśli dwa sklepy muszą obsługiwać paginację w odpowiedzi na różne akcje, muszą albo dziedziczyć ze wspólnego sklepu bazowego (źle! blokujesz się w konkretnym projekcie, gdy używasz dziedziczenia), lub wywołujesz funkcję z obsługi, która będzie musiała / align = "left" / Całość jest brudna (choć zdecydowanie w sferze możliwej).

Z drugiej strony, dzięki reduxowi paginacja jest naturalna dzięki składowi reduktora. To reduktory w dół, więc możesz napisać fabrykę reduktorów, która generuje reduktory paginacji , a następnie użyć go w swoim drzewie reduktora. Kluczem do tego, dlaczego jest to takie proste jest to, że W Flux, sklepy są płaskie, ale w Redux, reduktory mogą być zagnieżdżone poprzez kompozycja funkcjonalna, podobnie jak komponenty Reactowe mogą być zagnieżdżane.

Ten wzór umożliwia również wspaniałe funkcje, takie jak brak kodu użytkownika undo / redo. czy możesz sobie wyobrazić podłączenie Undo/Redo do aplikacji Flux jako dwóch linii kodu? Raczej nie. Z Reduxem jest to - znowu, dzięki wzorcowi składu reduktora. Muszę podkreślić, że nie ma w tym nic nowego-jest to wzór pionierski i szczegółowo opisany w architekturze Wiązów, na który sam wpływ miał / Align = "left" /

Rendering Serwera

Ludzie renderowali na serwerze dobrze z Flux, ale widząc, że mamy 20 bibliotek Flux, każda próbująca uczynić renderowanie serwera "łatwiejszym", być może Flux ma jakieś szorstkie krawędzie na serwerze. Prawda jest taka, że Facebook nie robi zbyt wiele renderowania serwerów, więc nie byli bardzo zaniepokojeni tym i polegają na ekosystemie, aby to ułatwić.

W tradycyjnym Flux, sklepy są singletony. Oznacza to, że trudno jest oddzielić dane dla różne żądania na serwerze. Nie niemożliwe, ale trudne. Z tego powodu większość bibliotek Flux (jak również nowe Utils) sugeruje teraz używanie klas zamiast singletonów, dzięki czemu można tworzyć instancje magazynów na żądanie.

Nadal istnieją następujące problemy, które musisz rozwiązać w Flux (samodzielnie lub przy pomocy ulubionej Biblioteki Flux, takiej jak Flummox lub Alt):

  • jeśli sklepy są klasami, jak je tworzyć i niszczyć z dyspozytorem na życzenie? Kiedy mogę zarejestrować sklepy?
  • jak nawodnić dane ze sklepów, a następnie nawodnić je na kliencie? Czy muszę wdrażać w tym celu specjalne metody?

Wprawdzie frameworki Flux (Nie vanilla Flux) mają rozwiązania tych problemów, ale uważam je za zbyt skomplikowane. Na przykład, Flummox prosi o zaimplementowanie serialize() i deserialize() w swoich sklepach. Alt rozwiązuje ten problem, dostarczając takeSnapshot() który automatycznie serializuje twój stan w drzewie JSON.

Redux idzie dalej: ponieważ istnieje tylko jeden sklep (zarządzany przez wiele reduktorów), nie potrzebujesz żadnego specjalnego API do zarządzania nawodnieniem. nie musisz "spłukiwać" ani "nawadniać" sklepów-jest tylko jeden sklep i możesz odczytać jego aktualny stan lub utworzyć nowy sklep z nowym stanem. Każde żądanie otrzymuje osobną instancję sklepu. Przeczytaj więcej o renderowaniu serwera z Redux.

Ponownie, jest to przypadek czegoś możliwe zarówno w Flux jak i Redux, ale biblioteki Flux rozwiązują ten problem wprowadzając mnóstwo API i konwencji, a Redux nawet nie musi go rozwiązywać, ponieważ nie ma tego problemu w pierwszej kolejności dzięki prostocie konceptualnej.

Doświadczenie Programistów

Nie zamierzałem Redux stać się popularną biblioteką Flux-napisałem ją, gdy pracowałem nad moim reacteurope talk on hot reloading with time travel . Miałem jeden główny cel: zrobić to możliwa jest zmiana kodu reduktora w locie lub nawet" zmiana przeszłości " poprzez Przekreślenie akcji i zobaczenie przeliczanego stanu.

Nie widziałem ani jednej biblioteki Flux, która byłaby w stanie to zrobić. React Hot Loader również na to nie pozwala-w rzeczywistości pęka, jeśli edytujesz Flux stores, ponieważ nie wie, co z nimi zrobić.

Gdy Redux musi przeładować kod reduktora, wywołuje replaceReducer(), a aplikacja działa z nowym kodem. In Flux, data a funkcje są splątane w sklepach Flux, więc nie można "po prostu zastąpić funkcji". Co więcej, musiałbyś jakoś ponownie zarejestrować nowe wersje u dyspozytora-czegoś Redux nawet nie ma.

Ekosystem

Redux posiada bogaty i szybko rozwijający się ekosystem. To dlatego, że zapewnia kilka punktów rozszerzeń, takich jak middleware . Został zaprojektowany z wykorzystaniem przypadków użycia, takich jak logging , wsparcie dla obietnic, Observables , routing, niezmienność dev sprawdza, uporczywość , itp. Nie wszystkie z nich okażą się przydatne, ale miło jest mieć dostęp do zestawu narzędzi, które można łatwo połączyć, aby współpracować.

Prostota

Redux zachowuje wszystkie zalety Flux (nagrywanie i odtwarzanie akcji, jednokierunkowy przepływ danych, zależne mutacje) i dodaje nowe korzyści (łatwe cofanie-ponawianie, ponowne ładowanie na gorąco) bez wprowadzania Dispatcher i store Rejestracja.

Utrzymanie go w prostocie jest ważne, ponieważ utrzymuje cię przy zdrowych zmysłach podczas wdrażania abstrakcji wyższego poziomu.

W przeciwieństwie do większości bibliotek Flux, Powierzchnia API Redux jest niewielka. Jeśli usuniesz Ostrzeżenia dewelopera, komentarze i kontrole zdrowego rozsądku, będzie to 99 linii. Nie ma skomplikowanego kodu asynchronicznego do debugowania.

Możesz przeczytać i zrozumieć Redux.

Zobacz także moja odpowiedź na minusy używania Redux w porównaniu do Flux.

 1846
Author: Dan Abramov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-27 06:19:08

W Quora ktoś mówi :

Po pierwsze, jest całkowicie możliwe pisanie aplikacji z Reactem bez / Align = "left" /

Również ten wizualny schemat który stworzyłem pokazuje Szybki podgląd obu, prawdopodobnie szybką odpowiedź dla osób, które nie chcą czytać całego wyjaśnienia: Flux vs Redux

Ale jeśli nadal chcesz wiedzieć więcej, Czytaj dalej.

Uważam, że powinieneś zacząć od czystego Reacta, a następnie nauczyć się Redux i Flux. Po tym, jak będziesz miał prawdziwe doświadczenie z Reactem, zobaczysz czy Redux jest pomocny dla Ciebie, czy nie.

Może poczujesz, że Redux jest właśnie dla Twojej aplikacji, a może ty dowiesz się, że Redux próbuje rozwiązać problem, którego nie jesteś naprawdę doświadcza.

Jeśli zaczniesz bezpośrednio z Redux, możesz skończyć z over-engineered kod, kod trudniejszy do utrzymania i z jeszcze większą ilością błędów i niż bez Redux.

Z Redux docs :

Motywacja
ponieważ wymagania dla aplikacji jednostronicowych JavaScript stają się coraz bardziej skomplikowane, nasze kod musi zarządzać większą liczbą Stanów niż kiedykolwiek wcześniej. Stan ten może obejmować odpowiedzi serwera i danych buforowanych, a także lokalnie utworzonych danych, które nie został jeszcze dodany do serwera. Zwiększa się również stan UI w złożoności, ponieważ musimy zarządzać aktywnymi trasami, wybrane zakładki, Spinnery, sterowanie paginacją i tak dalej.

Zarządzanie tym ciągle zmieniającym się stanem jest trudne. Jeśli model może zaktualizować inny model, a następnie Widok może zaktualizować model, który aktualizuje inny model, a to z kolei może spowodować aktualizację innego widoku. W niektórych punkt, nie rozumiesz już, co dzieje się w Twojej aplikacji, jak masz stracił kontrolę nad tym, kiedy, dlaczego i jak swojego stanu. Gdy system jest nieprzezroczysta i niedeterministyczna, trudno odtworzyć błędy lub dodać nowe funkcje.

Jakby to nie było wystarczająco złe, rozważ nowe wymagania stają się wspólne w rozwoju produktu front-end. Jako deweloperzy jesteśmy oczekuje obsługi aktualizacji, renderowania po stronie serwera, pobierania dane przed wykonaniem przejścia trasy i tak dalej. Znajdujemy siebie próba zarządzania złożonością, z którą nigdy nie mieliśmy do czynienia wcześniej i nieuchronnie zadajemy pytanie: czy nadszedł czas, aby się poddać? Na odpowiedź brzmi nie.

Ta złożoność jest trudna do opanowania, ponieważ mieszamy dwa pojęcia które są bardzo trudno rozumować umysłowi ludzkiemu o: mutacji i asynchroniczność. Nazywam je Mentos i Cola. Oba mogą być świetne, gdy rozdzieleni, ale razem tworzą bałagan. Biblioteki takie jak React spróbuj rozwiązać ten problem w warstwie widoku, usuwając oba asynchroniczna i bezpośrednia manipulacja DOM. Jednak zarządzanie stanem Twoje dane są pozostawione do ciebie. Tu pojawia się Redux.

Podążając śladami Flux, CQRS i Event Sourcing, Redux próby dokonania mutacje stanu przewidywalne przez narzucanie pewnych ograniczenia dotyczące sposobu i czasu aktualizacji. Ograniczenia te znajdują odzwierciedlenie w trzech zasadach Redux.

Również z Redux docs :

Podstawowe pojęcia
Sam Redux jest bardzo prosty.

Wyobraź sobie, że stan Twojej aplikacji jest opisany jako zwykły obiekt. Na przykład, stan aplikacji todo może wyglądać tak:

{
  todos: [{
    text: 'Eat food',
    completed: true
  }, {
    text: 'Exercise',
    completed: false
  }],
  visibilityFilter: 'SHOW_COMPLETED'
}

Ten obiekt jest jak "model" z tym wyjątkiem, że nie ma seterów. To jest tak, że różne części kodu nie mogą zmienić stanu arbitralnie, powodując trudne do odtworzenia błędy.

Aby zmienić coś w stanie, musisz wysłać akcję. Na action to zwykły obiekt JavaScript (zauważ, że nie wprowadzamy żadnych Magia?) to opisuje, co się stało. Oto kilka przykładowych działań:

{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }

Wymuszenie, że każda zmiana jest opisana jako działanie pozwala nam na jasne zrozumienie tego, co się dzieje w aplikacji. Jeśli coś zmienił się, wiemy dlaczego się zmienił. Działania są jak bułka Tartaczna tego, co stało się. Na koniec, aby połączyć stan i działania, piszemy funkcja zwana reduktorem. Znowu nie ma w tym nic magicznego - to tylko funkcja, która przyjmuje stan i akcję jako argumenty i zwraca Następny stan aplikacji. Trudno byłoby napisać taką funkcję dla duża aplikacja, więc piszemy mniejsze funkcje zarządzające częściami stanu:

function visibilityFilter(state = 'SHOW_ALL', action) {
  if (action.type === 'SET_VISIBILITY_FILTER') {
    return action.filter;
  } else {
    return state;
  }
}

function todos(state = [], action) {
  switch (action.type) {
  case 'ADD_TODO':
    return state.concat([{ text: action.text, completed: false }]);
  case 'TOGGLE_TODO':
    return state.map((todo, index) =>
      action.index === index ?
        { text: todo.text, completed: !todo.completed } :
        todo
   )
  default:
    return state;
  }
}

I piszemy kolejny reduktor, który zarządza całkowitym stanem naszego app wywołując te dwa reduktory dla odpowiednich kluczy stanu:

function todoApp(state = {}, action) {
  return {
    todos: todos(state.todos, action),
    visibilityFilter: visibilityFilter(state.visibilityFilter, action)
  };
}
To jest w zasadzie cała idea Redux. Zauważ, że nie użyliśmy wszystkie API Redux. Jest wyposażony w kilka narzędzi, aby to ułatwić wzorca, ale główną ideą jest to, że opisujesz swój stan aktualizowane w czasie w odpowiedzi na obiekty akcji, a 90% kodu piszesz to po prostu zwykły JavaScript, bez użycia samego Redux, jego APIs, lub każda Magia.
 82
Author: Alireza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-06 07:18:49

Najlepiej zacząć od przeczytania tego postu dana Abramova, gdzie omawia różne implementacje Flux i ich kompromisy w czasie, gdy pisał redux: The Evolution of Flux Framework

Po drugie strona z motywacjami, do której linkujesz, nie omawia tak naprawdę motywacji Redux, jak motywacji stojących za Flux (i reagowaniem). Trzy zasady {[2] } są bardziej specyficzne dla Redux, choć nadal nie zajmuje się różnicami w implementacji od standardowa Architektura Flux.

Zasadniczo Flux ma wiele magazynów, które obliczają zmiany stanu w odpowiedzi na interakcje UI/API z komponentami i transmitują te zmiany jako zdarzenia, które komponenty mogą subskrybować. W Redux jest tylko jeden sklep, do którego subskrybuje każdy komponent. IMO wydaje się, że Redux jeszcze bardziej upraszcza i unifikuje przepływ danych, unifikując (lub zmniejszając, jak powiedziałby Redux) przepływ danych z powrotem do komponentów - podczas gdy Flux koncentruje się na ujednolicenie drugiej strony przepływu danych - widok do modelu.

 52
Author: Hal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-26 00:47:49

Jestem początkującym użytkownikiem i zaimplementowałem średnio-dużą aplikację jednostronicową przy użyciu biblioteki Facebook Flux.

Ponieważ jestem trochę spóźniony na rozmowę, zaznaczę tylko, że pomimo moich największych nadziei, Facebook wydaje się uważać ich implementację Flux za dowód koncepcji i nigdy nie otrzymał uwagi, na którą zasługuje.

Zachęcam do zabawy, ponieważ eksponuje więcej wewnętrznego działania architektury Flux, która jest dość edukacyjna, ale jednocześnie czas nie zapewnia wielu korzyści, jakie zapewniają biblioteki takie jak Redux (które nie są tak ważne dla małych projektów, ale stają się bardzo cenne dla większych).

Zdecydowaliśmy, że idąc dalej przenosimy się na Redux i proponuję zrobić to samo;)

 23
Author: Guy Nesher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-05 13:45:53

Oto proste wyjaśnienie Redux nad Flux. Redux nie posiada dispatcher.It opiera się na czystych funkcjach zwanych reduktorami. Nie potrzebuje dyspozytora. Każda akcja jest obsługiwana przez jeden lub więcej reduktorów, aby zaktualizować pojedynczy magazyn. Ponieważ dane są niezmienne, reduktory zwracają nowy zaktualizowany stan, który aktualizuje SklepTutaj wpisz opis obrazka

Więcej informacji http://www.prathapkudupublog.com/2017/04/flux-vs-redux.html

 15
Author: Prathap Kudupu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-18 14:27:02

Pracowałem dość długo z Fluxem, a teraz dość długo z Reduxem. Jak zauważył Dan, obie architektury nie różnią się tak bardzo. Chodzi o to, że Redux sprawia, że rzeczy prostsze i czystsze. Uczy cię kilku rzeczy na topie. Jak na przykład Flux jest doskonałym przykładem jednokierunkowego przepływu danych. Rozdzielenie problemów, w których mamy dane, ich manipulacje i odseparowane warstwy widoku. W Redux mamy te same rzeczy, ale uczymy się również o niezmienności i czystości funkcje.

 3
Author: Krasimir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-25 12:26:44

Poza argumentami technicznymi opisanymi w poprzednich odpowiedziach, IMHO dwa ważne powody to:

  • Narzędzia: Redux dev tool jest niesamowite narzędzie, sprawia, że programista / debugowania doświadczenie wybuch (wehikuł czasu, możliwość eksportu sesji użytkownika i odtworzyć go w lokalnym środowisku...).

  • Stack overflow friendly: Redux uzyskał ponad 51000 wyników na stackoverflow, flux 9000.

 0
Author: Braulio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-30 10:27:07