Według dokumentów: „Bez oprogramowania pośredniego sklep Redux obsługuje tylko synchroniczny przepływ danych” . Nie rozumiem, dlaczego tak jest. Dlaczego składnik kontenera nie może wywołać interfejsu API asynchronicznego, a następnie dispatch
akcji?
Na przykład wyobraź sobie prosty interfejs użytkownika: pole i przycisk. Gdy użytkownik naciska przycisk, pole zostaje zapełnione danymi ze zdalnego serwera.
import * as React from 'react';
import * as Redux from 'redux';
import { Provider, connect } from 'react-redux';
const ActionTypes = {
STARTED_UPDATING: 'STARTED_UPDATING',
UPDATED: 'UPDATED'
};
class AsyncApi {
static getFieldValue() {
const promise = new Promise((resolve) => {
setTimeout(() => {
resolve(Math.floor(Math.random() * 100));
}, 1000);
});
return promise;
}
}
class App extends React.Component {
render() {
return (
<div>
<input value={this.props.field}/>
<button disabled={this.props.isWaiting} onClick={this.props.update}>Fetch</button>
{this.props.isWaiting && <div>Waiting...</div>}
</div>
);
}
}
App.propTypes = {
dispatch: React.PropTypes.func,
field: React.PropTypes.any,
isWaiting: React.PropTypes.bool
};
const reducer = (state = { field: 'No data', isWaiting: false }, action) => {
switch (action.type) {
case ActionTypes.STARTED_UPDATING:
return { ...state, isWaiting: true };
case ActionTypes.UPDATED:
return { ...state, isWaiting: false, field: action.payload };
default:
return state;
}
};
const store = Redux.createStore(reducer);
const ConnectedApp = connect(
(state) => {
return { ...state };
},
(dispatch) => {
return {
update: () => {
dispatch({
type: ActionTypes.STARTED_UPDATING
});
AsyncApi.getFieldValue()
.then(result => dispatch({
type: ActionTypes.UPDATED,
payload: result
}));
}
};
})(App);
export default class extends React.Component {
render() {
return <Provider store={store}><ConnectedApp/></Provider>;
}
}
Po wyrenderowaniu eksportowanego komponentu mogę kliknąć przycisk, a dane wejściowe zostaną poprawnie zaktualizowane.
Zanotuj update
funkcję w connect
połączeniu. Wysyła akcję informującą aplikację o aktualizacji, a następnie wykonuje połączenie asynchroniczne. Po zakończeniu połączenia podana wartość jest wysyłana jako ładunek innego działania.
Co jest złego w tym podejściu? Dlaczego miałbym chcieć używać Redux Thunk lub Redux Promise, jak sugeruje dokumentacja?
EDYCJA: Przeszukałem repozytorium Redux w poszukiwaniu wskazówek i odkryłem, że Action Creators w przeszłości wymagały czystych funkcji. Na przykład użytkownik próbuje lepiej wyjaśnić przepływ danych asynchronicznych:
Sam twórca akcji jest nadal czystą funkcją, ale zwięzła funkcja, którą zwraca, nie musi być i może wykonywać nasze wywołania asynchroniczne
Twórcy akcji nie są już zobowiązani do zachowania czystości. Tak więc w przeszłości zdecydowanie wymagane było oprogramowanie pośrednie typu thunk / obiec, ale wydaje się, że tak już nie jest?
źródło
Odpowiedzi:
W tym podejściu nie ma nic złego. Jest to po prostu niewygodne w dużej aplikacji, ponieważ będziesz mieć różne komponenty wykonujące te same akcje, możesz chcieć ogłosić niektóre akcje lub utrzymać stan lokalny, taki jak automatyczne zwiększanie identyfikatorów blisko twórców akcji itp. Więc jest to po prostu łatwiejsze od punkt widzenia utrzymania, aby wyodrębnić twórców akcji do oddzielnych funkcji.
Możesz przeczytać moją odpowiedź na „Jak wysłać akcję Redux z limitem czasu”, aby uzyskać bardziej szczegółowy przewodnik.
Oprogramowanie pośrednie, takie jak Redux Thunk lub Redux Promise, po prostu daje „cukier składniowy” do wysyłania thunks lub obietnic, ale nie trzeba go używać.
Więc bez pośredniego oprogramowania może wyglądać Twój twórca akcji
Ale dzięki Thunk Middleware możesz to napisać w następujący sposób:
Więc nie ma ogromnej różnicy. Jedną z rzeczy, które lubię w tym drugim podejściu, jest to, że komponent nie dba o to, by twórca akcji był asynchroniczny. Po prostu wywołuje
dispatch
normalnie, można go również użyćmapDispatchToProps
do powiązania takiego twórcy akcji krótką składnią itp. Składniki nie wiedzą, jak są implementowane twórcy akcji, i można przełączać się między różnymi podejściami asynchronicznymi (Redux Thunk, Redux Promise, Redux Saga ) bez zmiany komponentów. Z drugiej strony, przy pierwszym, jawnym podejściu, komponenty wiedzą dokładnie, że określone wywołanie jest asynchroniczne i musidispatch
zostać przekazane przez pewną konwencję (na przykład jako parametr synchronizacji).Zastanów się także, jak ten kod się zmieni. Powiedzmy, że chcemy mieć drugą funkcję ładowania danych i połączyć je w jednym kreatorze akcji.
Przy pierwszym podejściu musimy pamiętać o tym, jakiego rodzaju twórcę akcji nazywamy:
Dzięki Redux Thunk twórcy akcji mogą
dispatch
wynikać z działania innych twórców akcji, a nawet nie myśleć, czy są oni synchroniczni czy asynchroniczni:Dzięki takiemu podejściu, jeśli później chcesz, aby twórcy akcji sprawdzili aktualny stan Redux, możesz po prostu użyć drugiego
getState
argumentu przekazanego thunksom bez modyfikacji kodu wywołującego:Jeśli chcesz go zmienić, aby był synchroniczny, możesz to zrobić również bez zmiany kodu wywoławczego:
Zaletą korzystania z oprogramowania pośredniego, takiego jak Redux Thunk lub Redux Promise, jest to, że komponenty nie są świadome, w jaki sposób implementowani są twórcy akcji i czy dbają o stan Redux, czy są synchroniczne czy asynchroniczne oraz czy wywołują innych twórców akcji . Minusem jest trochę pośredniość, ale uważamy, że warto w prawdziwych zastosowaniach.
Wreszcie, Redux Thunk i przyjaciele to tylko jedno z możliwych podejść do asynchronicznych żądań w aplikacjach Redux. Innym interesującym podejściem jest Saga Redux, która pozwala definiować długo działające demony („sagi”), które podejmują działania w miarę ich pojawiania się oraz przekształcają lub wykonują żądania przed wydaniem działań. To przenosi logikę z twórców akcji do sag. Możesz to sprawdzić, a później wybrać to, co najbardziej Ci odpowiada.
To jest niepoprawne. Dokumenty to powiedziały, ale dokumenty były błędne.
Twórcy akcji nigdy nie musieli być czystymi funkcjami.
Naprawiliśmy dokumenty, aby to odzwierciedlić.
źródło
alert
podispatch()
akcji.loadData(this.props.dispatch, this.props.userId); // don't forget to pass dispatch
. Dlaczego muszę przekazać przesyłkę? Jeśli zgodnie z konwencją istnieje tylko jeden globalny sklep, dlaczego po prostu nie odwołuję się do tego bezpośrednio i robię tostore.dispatch
za każdym razem , gdy muszę, np. WejśćloadData
?store
instancję dla każdego żądania, abyś nie mógł go wcześniej zdefiniować.Ty nie.
Ale ... powinieneś użyć redux-saga :)
Odpowiedź Dana Abramova jest słuszna,
redux-thunk
ale powiem trochę więcej o sadze redux, która jest dość podobna, ale mocniejsza.Tryb rozkazujący a deklaratywny
redux-thunk
jest konieczny /redux-saga
deklaratywnyKiedy masz w ręku kutasa, jak monada IO lub obietnica, nie możesz łatwo wiedzieć, co zrobi po wykonaniu. Jedynym sposobem przetestowania thunk jest wykonanie go i wyśmiewanie się z dyspozytora (lub całego świata zewnętrznego, jeśli wchodzi on w interakcje z większą ilością rzeczy ...).
Jeśli korzystasz z prób, nie wykonujesz programowania funkcjonalnego.
Źródło
Sagi (po ich zaimplementowaniu
redux-saga
) są deklaratywne i podobnie jak komponenty Free monad lub React, są znacznie łatwiejsze do przetestowania bez żadnego próbnego.Zobacz także ten artykuł :
(W rzeczywistości saga Redux jest jak hybryda: przepływ jest konieczny, ale efekty są deklaratywne)
Zamieszanie: akcje / zdarzenia / polecenia ...
W świecie frontendu istnieje wiele nieporozumień co do tego, w jaki sposób niektóre koncepcje backendu, takie jak CQRS / EventSourcing i Flux / Redux, mogą być powiązane, głównie dlatego, że w Flux używamy terminu „akcja”, który może czasami reprezentować zarówno imperatywny kod (
LOAD_USER
), jak i zdarzenia (USER_LOADED
). Uważam, że podobnie jak pozyskiwanie wydarzeń, powinieneś wysyłać tylko zdarzenia.Wykorzystywanie sag w praktyce
Wyobraź sobie aplikację z linkiem do profilu użytkownika. Idiomatycznym sposobem radzenia sobie z tym z każdym oprogramowaniem pośrednim byłoby:
redux-thunk
redux-saga
Ta saga przekłada się na:
Jak widać, istnieją pewne zalety
redux-saga
.Użycie
takeLatest
zezwoleń na wyrażenie, że jesteś zainteresowany jedynie uzyskaniem danych o ostatniej klikniętej nazwie użytkownika (radzisz sobie z problemami dotyczącymi współbieżności w przypadku, gdy użytkownik kliknie bardzo szybko wiele nazw użytkowników). Tego rodzaju rzeczy są trudne do zrobienia. Możesz użyć,takeEvery
jeśli nie chcesz tego zachowania.Dbasz o czystość twórców akcji. Pamiętaj, że nadal warto zachować ActionCreators (w sagach
put
i komponentachdispatch
), ponieważ może to pomóc w dodaniu sprawdzania poprawności akcji (asercje / przepływ / maszynopis) w przyszłości.Twój kod staje się znacznie bardziej testowalny, ponieważ efekty są deklaratywne
Już nie potrzebujesz, aby wywoływać połączenia podobne do RPC
actions.loadUser()
. Twój interfejs użytkownika musi tylko wysłać to, co się stało. Odpalamy tylko zdarzenia (zawsze w czasie przeszłym!), A nie akcje. Oznacza to, że możesz tworzyć oddzielone „kaczki” lub ograniczone konteksty i że saga może działać jako punkt sprzężenia między tymi modułowymi elementami.Oznacza to, że Twoje widoki są łatwiejsze do zarządzania, ponieważ nie muszą już zawierać tej warstwy tłumaczenia między tym, co się wydarzyło, a tym, co powinno się stać efektem
Na przykład wyobraź sobie nieskończony widok przewijania.
CONTAINER_SCROLLED
może prowadzić doNEXT_PAGE_LOADED
, ale czy tak naprawdę to na przewijanym kontenerze spoczywa decyzja, czy należy załadować inną stronę? Następnie musi zdawać sobie sprawę z bardziej skomplikowanych rzeczy, takich jak to, czy ostatnia strona została pomyślnie załadowana, czy jest już strona, która próbuje się załadować, czy też nie ma już więcej elementów do załadowania? Nie sądzę: dla maksymalnej możliwości wielokrotnego użytku przewijany pojemnik powinien po prostu opisać, że został przewinięty. Ładowanie strony jest „efektem biznesowym” tego zwojuNiektórzy mogą argumentować, że generatory mogą z natury ukrywać stan poza magazynem redux za pomocą zmiennych lokalnych, ale jeśli zaczniesz aranżować skomplikowane rzeczy wewnątrz thunks poprzez uruchomienie timerów itp., I tak będziesz miał ten sam problem. I istnieje
select
efekt, który pozwala teraz uzyskać pewien stan ze sklepu Redux.Sagi można podróżować w czasie, a także umożliwia złożone rejestrowanie przepływu i narzędzia deweloperskie, nad którymi obecnie pracujemy. Oto kilka prostych zapisów przepływu asynchronicznego, które zostały już zaimplementowane:
Oddzielenie
Sagi nie tylko zastępują redux thunks. Pochodzą z backendu / systemów rozproszonych / pozyskiwania zdarzeń.
Bardzo powszechne jest błędne przekonanie, że sagi są tutaj po to, aby zastąpić twoje redukcje lepszymi testami. W rzeczywistości jest to tylko szczegół implementacji redux-sagi. Użycie efektów deklaratywnych jest lepsze niż testowanie, ale wzorzec sagi można zaimplementować na podstawie kodu rozkazującego lub deklaratywnego.
Po pierwsze, saga to oprogramowanie, które pozwala na koordynację długo trwających transakcji (ostateczna spójność) i transakcji w różnych kontekstach (żargon projektowy oparty na domenie).
Aby uprościć to dla frontendowego świata, wyobraź sobie, że jest widget1 i widget2. Kliknięcie przycisku na widżecie1 powinno mieć wpływ na widżet2. Zamiast łączyć dwa widżety razem (tj. Widget1 wywołuje akcję skierowaną na widget2), widget1 wywołuje tylko kliknięcie jego przycisku. Następnie saga nasłuchuje kliknięcia tego przycisku, a następnie aktualizuje widget2, usuwając nowe zdarzenie, o którym widget2 jest świadomy.
Dodaje to poziomu pośrednictwa, który nie jest konieczny w przypadku prostych aplikacji, ale ułatwia skalowanie złożonych aplikacji. Teraz możesz publikować widget1 i widget2 w różnych repozytoriach npm, aby nigdy nie musieli się o sobie znać bez konieczności udostępniania im globalnego rejestru działań. Dwa widżety są teraz ograniczonymi kontekstami, które mogą żyć osobno. Nie muszą się nawzajem zachowywać spójności i mogą być ponownie wykorzystywane w innych aplikacjach. Saga jest punktem połączenia między dwoma widżetami, które koordynują je w znaczący sposób dla Twojej firmy.
Kilka ciekawych artykułów na temat struktury aplikacji Redux, na których możesz używać sagi Redux z powodów oddzielania:
Konkretny przypadek użycia: system powiadomień
Chcę, aby moje komponenty mogły wyświetlać powiadomienia w aplikacji. Ale nie chcę, aby moje komponenty były silnie sprzężone z systemem powiadomień, który ma własne reguły biznesowe (maks. 3 powiadomienia wyświetlane jednocześnie, kolejkowanie powiadomień, czas wyświetlania 4 sekundy itp.).
Nie chcę, aby moje komponenty JSX decydowały, kiedy powiadomienie zostanie wyświetlone / ukryte. Po prostu daję mu możliwość zażądania powiadomienia i pozostawienie skomplikowanych zasad w sadze. Tego rodzaju rzeczy są dość trudne do zrealizowania za pomocą gromad lub obietnic.
Opisałem tutaj, jak można to zrobić za pomocą sagi
Dlaczego nazywa się Saga?
Termin saga pochodzi ze świata zaplecza. Początkowo wprowadziłem do tego terminu Yassine (autor redagi-sagi) w długiej dyskusji .
Początkowo termin ten został wprowadzony w formie papierowej , wzorzec sagi miał być używany do obsługi ostatecznej spójności w transakcjach rozproszonych, ale jego użycie zostało rozszerzone na szerszą definicję przez programistów backendu, tak że teraz obejmuje również „menedżera procesów” wzorzec (w jakiś sposób oryginalny wzorzec sagi jest wyspecjalizowaną formą menedżera procesów).
Dzisiaj termin „saga” jest mylący, ponieważ może opisać 2 różne rzeczy. Używany w sadze redux nie opisuje sposobu obsługi transakcji rozproszonych, ale raczej sposób koordynacji działań w Twojej aplikacji.
redux-saga
można by również nazwaćredux-process-manager
.Zobacz też:
Alternatywy
Jeśli nie podoba ci się pomysł użycia generatorów, ale interesuje Cię wzorzec sagi i jego właściwości oddzielające, możesz również osiągnąć to samo z obserwowalnym redux, który używa nazwy
epic
do opisania dokładnie tego samego wzorca, ale z RxJS. Jeśli znasz już Rx, poczujesz się jak w domu.Niektóre przydatne sagi redux
2017 r
yield put(someActionThunk)
jeśli ma to sens.Jeśli boisz się używać sagi Redux (lub obserwowalnej w Redux), ale potrzebujesz jedynie wzoru oddzielenia, sprawdź redux-dispatch-subscribe : pozwala na słuchanie wysyłek i wyzwalanie nowych wysyłek w słuchaczu.
źródło
ADD_ITEM
, jest to konieczne, ponieważ wysyłasz akcję, która ma na celu wywarcie wpływu na Twój sklep: oczekujesz, że akcja coś zrobi. Będąc deklaratywnym, zastosuj filozofię pozyskiwania zdarzeń: nie wywołujesz działań w celu wywołania zmian w swoich aplikacjach, ale wysyłasz zdarzenia z przeszłości, aby opisać, co się stało z twoją aplikacją. Wysłanie zdarzenia powinno wystarczyć, aby uznać, że stan aplikacji zmienił się. Fakt, że istnieje sklep Redux, który reaguje na zdarzenie, jest opcjonalnym szczegółem implementacjiKrótka odpowiedź : wydaje mi się całkowicie rozsądnym podejściem do problemu asynchronicznego. Z kilkoma zastrzeżeniami.
Miałem bardzo podobny tok myślenia podczas pracy nad nowym projektem, który właśnie rozpoczęliśmy w mojej pracy. Byłem wielkim fanem eleganckiego systemu waniliowego Redux do aktualizowania sklepu i ponownego wysyłania komponentów w sposób, który pozostaje poza wnętrzem drzewa komponentów React. Wydawało mi się dziwne podłączenie się do tego eleganckiego
dispatch
mechanizmu do obsługi asynchronii.Skończyłem z bardzo podobnym podejściem do tego, co masz w bibliotece, którą uwzględniłem w naszym projekcie, który nazwaliśmy reakcją-kontrolerem-reduksem .
Skończyło się na tym, że nie podążyłem dokładnie takim podejściem z kilku powodów:
dispatch
siebie poprzez zakres leksykalny. Ogranicza to opcje refaktoryzacji, gdyconnect
instrukcja wymknie się spod kontroli - i wygląda to dość niewygodnie z tą jednąupdate
metodą. Potrzebujesz więc systemu umożliwiającego komponowanie funkcji dyspozytora, jeśli podzielisz je na osobne moduły.Podsumowując, musisz skonfigurować jakiś system, aby zezwolić
dispatch
i sklep zostanie wprowadzony do twoich funkcji wysyłkowych, wraz z parametrami zdarzenia. Znam trzy rozsądne podejścia do tego zastrzyku zależności:dispatch
metodami oprogramowania pośredniego, ale zakładam, że są one w zasadzie takie same.connect
, zamiast konieczności bezpośredniej pracy z surowym, znormalizowanym sklepem.this
kontekstu za pomocą różnych możliwych mechanizmów.Aktualizacja
Przyszło mi do głowy, że część tej zagadki jest ograniczeniem ponownego reagowania . Pierwszy argument, który
connect
pobiera migawkę stanu, ale nie wysyła. Drugi argument zostanie wysłany, ale nie stan. Żaden argument nie dostaje thunk, który zamyka się nad bieżącym stanem, za możliwość zobaczenia zaktualizowanego stanu w czasie kontynuacji / oddzwaniania.źródło
Celem Abramova - i idealnie dla wszystkich - jest po prostu hermetyzacja złożoności (i asynchronicznych połączeń) w miejscu, w którym jest to najbardziej odpowiednie .
Gdzie najlepiej to zrobić w standardowym przepływie danych Redux? Co powiesz na:
źródło
Aby odpowiedzieć na pytanie zadane na początku:
Pamiętaj, że te dokumenty dotyczą Redux, a nie Redux plus React. Sklepy Redux podłączone do komponentów React mogą robić dokładnie to, co mówisz, ale sklep Plain Jane Redux bez oprogramowania pośredniego nie przyjmuje argumentów
dispatch
oprócz zwykłych obiektów ol.Bez oprogramowania pośredniego można oczywiście nadal
Ale jest to podobny przypadek, w którym asynchronia jest owinięta wokół Redux, a nie obsługiwana przez Redux. Oprogramowanie pośrednie pozwala więc na asynchronię poprzez modyfikację tego, co można przekazać bezpośrednio
dispatch
.To powiedziawszy, duch waszej sugestii jest, jak sądzę, ważny. Z pewnością istnieją inne sposoby obsługi asynchronii w aplikacji Redux + React.
Jedną z zalet korzystania z oprogramowania pośredniego jest to, że możesz nadal używać kreatorów akcji bez normalnego martwienia się o to, jak są podłączeni. Na przykład przy użyciu
redux-thunk
napisany kod wyglądałby bardzo podobniektóry nie wygląda tak różnie od oryginału - jest tylko trochę przetasowany - i
connect
nie wie, żeupdateThing
jest (lub musi być) asynchroniczny.Jeśli chcesz także wspierać obietnice , obserwowalne , sagi lub zwariowanych niestandardowych i wysoce deklaratywnych twórców akcji, Redux może to zrobić, zmieniając to, co przekazujesz
dispatch
(czyli to, co powrócisz od twórców akcji). Nieconnect
trzeba tłumić komponentów React (ani wywołań).źródło
OK, zacznijmy od tego, jak najpierw działa oprogramowanie pośrednie, które dość odpowiada na pytanie, to jest kod źródłowy funkcji pplyMiddleWare w Redux:
Spójrz na tę część, zobacz, jak nasza wysyłka stała się funkcją .
OK, oto jak Redux-thunk jako jeden z najczęściej używanych programów pośrednich dla Redux przedstawia się:
Jak więc widzisz, funkcja zwróci funkcję zamiast akcji, co oznacza, że możesz poczekać i wywołać ją w dowolnym momencie, ponieważ jest to funkcja ...
Więc co, u licha, jest gromkie? Tak to zostało przedstawione w Wikipedii:
Zobacz, jak prosta jest ta koncepcja i jak może pomóc Ci zarządzać działaniami asynchronicznymi ...
To jest coś, bez czego możesz żyć, ale pamiętaj, że w programowaniu zawsze są lepsze, schludniejsze i odpowiednie sposoby robienia rzeczy ...
źródło
Saga Redux-saga jest najlepszym oprogramowaniem pośrednim w implementacji React-redux.
Np .: store.js
A potem saga.js
A potem action.js
A potem reder.js
A potem main.js
spróbuj tego .. działa
źródło
Są twórcy akcji synchronicznych, a następnie są twórcy akcji asynchronicznych.
Synchroniczny twórca akcji to taki, który gdy go nazwiemy, natychmiast zwraca obiekt Action ze wszystkimi odpowiednimi danymi dołączonymi do tego obiektu i gotowy do przetworzenia przez nasze reduktory.
Twórcy akcji asynchronicznych to takie, w których przygotowanie zajmie trochę czasu.
Z definicji, ilekroć masz kreatora akcji, który wysyła żądanie sieciowe, zawsze będzie się kwalifikował jako kreator akcji asynchronicznych.
Jeśli chcesz mieć asynchronicznych twórców akcji w aplikacji Redux, musisz zainstalować coś, co nazywa się oprogramowaniem pośrednim, które pozwoli ci radzić sobie z tymi asynchronicznymi twórcami akcji.
Możesz to sprawdzić w komunikacie o błędzie informującym, że używamy niestandardowego oprogramowania pośredniego do akcji asynchronicznych.
Czym jest oprogramowanie pośrednie i dlaczego potrzebujemy go do przepływu asynchronicznego w Redux?
W kontekście reduksowego oprogramowania pośredniego, takiego jak redux-thunk, oprogramowanie pośrednie pomaga nam radzić sobie z twórcami działań asynchronicznych, ponieważ jest to coś, czego Redux nie jest w stanie obsłużyć po wyjęciu z pudełka.
Dzięki oprogramowaniu pośredniczącemu zintegrowanemu z cyklem Redux nadal wzywamy twórców akcji, którzy zwrócą akcję, która zostanie wysłana, ale teraz, gdy wysyłamy akcję, zamiast wysyłać ją bezpośrednio do wszystkich naszych reduktorów, zamierzamy aby powiedzieć, że akcja zostanie wysłana przez różne oprogramowanie pośrednie wewnątrz aplikacji.
Wewnątrz jednej aplikacji Redux możemy mieć tyle lub mniej oprogramowania pośredniego, ile chcemy. W większości przypadków w projektach, nad którymi pracujemy, do naszego sklepu Redux zostanie podłączone jedno lub dwa oprogramowanie pośrednie.
Oprogramowanie pośrednie to zwykła funkcja JavaScript, która będzie wywoływana przy każdym wykonywanym przez nas działaniu. Wewnątrz tej funkcji oprogramowanie pośrednie ma możliwość zatrzymania wysyłania akcji do dowolnego reduktora, może modyfikować akcję lub po prostu zadzierać z akcją w dowolny sposób, który na przykład możemy stworzyć oprogramowanie pośredniczące, które loguje konsolę każdą akcję, którą wykonujesz tylko dla przyjemności oglądania.
Istnieje ogromna liczba oprogramowania pośredniego typu open source, które można zainstalować jako zależności w projekcie.
Nie jesteś ograniczony tylko do korzystania z oprogramowania pośredniego typu open source lub instalowania ich jako zależności. Możesz napisać własne niestandardowe oprogramowanie pośrednie i używać go w sklepie Redux.
Jednym z bardziej popularnych zastosowań oprogramowania pośredniego (i uzyskania odpowiedzi) jest praca z twórcami działań asynchronicznych, prawdopodobnie najpopularniejszym oprogramowaniem pośrednim jest redux-thunk i pomoc w radzeniu sobie z twórcami działań asynchronicznych.
Istnieje wiele innych rodzajów oprogramowania pośredniego, które również pomagają w radzeniu sobie z twórcami działań asynchronicznych.
źródło
Aby odpowiedzieć na pytanie:
Powiedziałbym z co najmniej dwóch powodów:
Pierwszym powodem jest rozdzielenie obaw, nie jest zadaniem
action creator
oddzwanianieapi
i odzyskiwanie danych, musisz przekazać dwa argumenty swojemuaction creator function
,action type
ipayload
.Drugi powód jest taki, że
redux store
czeka na zwykły obiekt z obowiązkowym typem akcji i opcjonalnie apayload
(ale tutaj musisz również przekazać ładunek).Kreator akcji powinien być prostym obiektem, takim jak poniżej:
I zadanie
Redux-Thunk midleware
dodispache
wyniku swojegoapi call
do odpowiedniegoaction
.źródło
Podczas pracy w projekcie korporacyjnym istnieje wiele wymagań dostępnych w oprogramowaniu pośrednim, takich jak (saga) niedostępnych w prostym przepływie asynchronicznym, poniżej niektóre:
Lista jest długa, wystarczy przejrzeć sekcję zaawansowaną w dokumentacji sagi
źródło