En introduktion til Redux-Logic

Denne artikel gennemgår en oversigt på højt niveau af Redux-Logic. Vi vil se på, hvad der er, hvorfor det er nødvendigt, hvordan det adskiller sig fra anden Redux middleware, og hvorfor jeg synes, det er det bedste valg. Vi vil så se et eksempel på en simpel Weather-app for at demonstrere, hvordan kernekoncepterne omsættes i praksis.

Denne artikel forudsætter, at du har en god forståelse af React og Redux.

En hurtig opdatering på Redux

Redux er en tilstandscontainer til JavaScript-applikationer og bruges ofte sammen med React. Det giver et centralt sted til lagring af data, der bruges i hele din applikation. Redux giver også en ramme til at foretage forudsigelige tilstandsmutationer. Brug af Redux gør det lettere at skrive, forstå, fejlfinde og skalere datadrevne og dynamiske applikationer.

I Redux kalder komponenter handlingsskabere, der sender handlinger . Handlinger er (normalt!) Små almindelige objekter, der udtrykker en hensigt eller en instruktion. Handlingerne kan også indeholde 'nyttelast' (dvs. data).

Ansøgningstilstand styres af reduceringsanordninger . De lyder mere komplicerede end de er! Handlinger håndteres af en rodreducer, som derefter overfører handlingen og nyttelasten til en bestemt reducer. Denne reducering vil tage en kopi af ansøgningen tilstand, mutere den kopi (i henhold til aktionen og dens nyttelast), og derefter opdatere tilstanden i ansøgningen Store .

Hvorfor behovet for Redux Logic?

Som standard sendes alle handlinger i Redux synkront. Dette udgør en udfordring for ethvert program, der har brug for at understøtte asynkron opførsel, såsom at hente data fra en API ... så stort set enhver applikation!

For at håndtere asynkroniseringsadfærd ved hjælp af Redux har vi brug for en slags middleware, der udfører en vis behandling mellem, når handlingen sendes, og når handlingen når reduceringerne. Der er flere populære biblioteker til at levere denne funktionalitet.

Efter at have undersøgt de forskellige muligheder har jeg brugt Redux-Logic i en række projekter i et stykke tid nu og har fundet det godt!

Redux-Logic livscyklus

Redux-Logic leverer middleware, der udfører en vis behandling mellem når en handling sendes fra en komponent, og når handlingen når en reducer.

Vi bruger redux-logic-biblioteket til at oprette 'Logic'. Disse er i det væsentlige funktioner, der opfanger bestemte handlinger med almindeligt objekt , udfører asynkron behandling og derefter sender en anden almindelig objekthandling . Logiske funktioner er virkelig deklarative og fleksible, som vi skal se!

En vigtig ting at tage væk her er, at alle handlinger, som Redux-Logic arbejder med, er almindelige objekter . Handlingen, der sendes af UI-komponenten, og den handling, der derefter sendes af Logikken, vil altid være et almindeligt objekt (i modsætning til for eksempel en funktion). Vi gennemgår dette nedenfor, når vi sammenligner forskellige middleware-muligheder.

Under emhætten bruger Redux-Logic 'observerbare' og reaktiv programmering. Læs mere om det her.

Datastrøm

Nedenfor er til sammenligning et diagram, jeg oprettede, der viser de vigtige punkter i livscyklussen for en synkron redux-proces. Der er ingen middleware inkluderet (fordi ingen er nødvendige!).

Her er et diagram, der viser de vigtige dele af et projekt, der bruger redux-logic-biblioteket til at håndtere asynkrone handlinger. Dette vil være nyttigt at henvise til senere sammen med nedenstående eksempel.

Du kan se, hvordan middlewaren fungerer imellem, når en handling sendes, og når den håndteres af en reducer.

Vigtigste forskelle fra andre løsninger

Redux-Thunk er et populært valg til Redux middleware, der også giver dig mulighed for at understøtte asynkron opførsel. For at håndtere asynkron opførsel ved hjælp af Redux-Thunk skal dine handlingskabere returnere funktioner i modsætning til at returnere almindelige objekter med Redux-Logic. Jeg tror, ​​at afsendelse af almindelige objekter med Redux-Logic gør din kode meget lettere at skrive og meget lettere at forstå.

Desuden mener jeg, at 'almindeligt objekt' tilgang til håndtering af asynkron opførsel passer mere naturligt sammen med resten af ​​(synkron) Redux-arkitekturen, hvilket gør denne middleware mere organisk med Redux.

En anden populær Redux middleware er Redux-Saga . Jeg fandt indlæringskurven for at få mit hoved omkring sagaer (en relativt ny ES6-funktion) ret stejl, da jeg kiggede på denne mulighed. Dette ville blive forværret, hvis du ville introducere dette bibliotek i en applikation, der administreres af et team med flere personer. Derudover tror jeg, at hvis de ikke administreres godt, kan sagaer skabe en kompliceret kode i forhold til den logik, du opretter med redux-logik. Dette kan påvirke udviklingshastighed og vedligeholdelse af kode.

Oversigt over eksemplet

Nedenfor er enkle uddrag fra et simpelt React-program, der kan hente de aktuelle vejrforhold i en by og præsentere det for brugeren. Eksemplet bruger Redux-Logic til at understøtte asynkron opførsel til at hente data ved hjælp af en gratis OpenWeatherMap API.

Til sammenligning har jeg inkluderet en synkron Redux-proces, der viser antallet af anmodninger, en bruger har fremsat.

Her er kildekoden.

Opsætning af udviklingsmiljø

Dette er de kommandoer, jeg løb for at begynde at oprette min applikation:

npx create-react-app appnpm install --save reduxnpm install --save react-reduxnpm install --save redux-logicnpm install --save axios

Og for at se appen:

npm start

Glad for, at jeg kunne se standard Create React App-hjemmesiden på localhost: 3000 , så begyndte jeg at skrive noget kode!

Nedenfor er kodestykker, der viser de vigtige punkter ved integrering af Redux-Logic i projektet.

Tilføjelse af middleware til vores Redux-butik

I appStore.js , hvis vi ikke brugte nogen middleware, ville vi normalt kun levere vores rodreducerende til createStore-metoden. Det er her, vi forbinder vores Redux-Logic middleware til resten af ​​vores applikation.

Vi specificerer, at vi vil bruge axios som vores klient til at foretage HTTP-anmodninger.

Vi bruger derefter en metode fra redux-logik til at oprette vores middleware, og til sidst tilføjer vi den som en parameter til createStore-metoden. Dette betyder, at vores Redux-kode vil have adgang til vores middleware. Store!

Afsendelse af asynkrone handlinger

Med Redux-Logic sendes handlinger, der udløser asynkron adfærd, på samme måde som handlinger, der udløser opdateringer af synkron tilstand. Der er ikke noget andet!

For fuldstændighed kan du se nedenfor, at når en bruger klikker på en knap, kalder vi en handlingsskaber, der er sendt til vores komponent som rekvisitter.

Opfangning af asynkrone handlinger

Det er her, vi først ser fremkomsten af ​​redux-logisk middleware komme i spil. Vi bruger redux-logic-biblioteket til at skabe nogle 'Logic', der vil opfange specificerede handlinger.

I vores logiske egenskaber fortæller vi redux-logik, hvilken handling vi vil have den til at opfange. Vi specificerer, at vi ønsker, at redux-logik kun leverer data fra den sidste handling af denne type, som komponenten sendte. I vores eksempel er denne deklarative opførsel nyttig, hvis folk bliver ved med at klikke på en knap, da de får værdien fra den seneste handling, de sendte, ikke nødvendigvis det sidste løfte om at vende tilbage!

Næste vi angiver, at når de asynkrone proces returnerer vi straks sende en af to handlinger. Hvis løftet returneres med succes, returnerer vi en GET_WEATHER_FOR_CITY_SUCCESSFUL handling. Dette er hvad vi vil have!

Alternativt, hvis det returnerede løfte blev afvist, sender vi GET_WEATHER_FOR_CITY_FAILURE .

Det er her, redux-logik virkelig skinner . Det er klart, hvad hensigten med Logic-koden er, og hvad der udsendes er enkle objekter, der er lette at læse og fortolke! Jeg finder det meget let at læse, forstå og fejlfinde.

Nederst gør vi det klart, hvad vi ønsker, at vores asynkrone proces skal gøre. Vi ønsker at returnere værdien af ​​et løfte. Læg mærke til, hvordan vi sender den nyttelast, der fulgte med vores handling, ind i URL'en.

Behandling af asynkrone handlinger

Du kan se fra weatherDataHandling.js-reducereren, at de handlinger, der sendes fra vores logik, derefter behandles som almindelige objekthandlinger . Reduktioner muterer tilstand på samme måde som med synkron handlinger . Så skærmbilledet nedenfor er, hvad du ville forvente af at arbejde med Redux før. Super!

Resumé

Redux er en populær forudsigelig tilstandscontainer til JavaScript-applikationer. Som standard understøtter alle Redux-handlinger kun synkron opførsel, og du har brug for en slags middleware-løsning til asynkron opførsel.

Redux-Logic giver en klar og kraftig middleware, der giver dig mulighed for at bruge asynkrone handlinger i din Redux-applikation. Du tilføjer din middleware til din Redux Store, så din applikation kan bruge Redux-Logic. Du bruger redux-logic-biblioteket til at oprette Logic, der opfanger bestemte handlinger og sender yderligere handlinger, når en vis asynkron behandling (som at hente data fra en API) er afsluttet.

Alle de involverede handlinger er almindelige objekthandlinger . Jeg tror, ​​det gør det lettere at skrive og lettere forstået sammenlignet med andre løsninger. Desuden føles redux-logik som en mere organisk pasform med de andre dele af Redux-arkitekturen.

Tak for læsningen. Jeg glæder mig over eventuelle kommentarer eller spørgsmål nedenfor!