Redux · O introducere
Publicat: 2022-03-10Redux este una dintre cele mai populare biblioteci în dezvoltarea front-end în aceste zile. Cu toate acestea, mulți oameni sunt confuzi cu privire la ce este și care sunt beneficiile sale.
După cum se arată în documentație, Redux este un container de stare previzibil pentru aplicațiile JavaScript. Pentru a reformula asta, este o arhitectură de flux de date de aplicație, mai degrabă decât o bibliotecă tradițională sau un cadru precum Underscore.js și AngularJS.
Citiți suplimentare despre SmashingMag
- De ce ar trebui să luați în considerare React Native pentru aplicația dvs. mobilă
- Testați automatizarea pentru aplicații, jocuri și web mobil
- Redare pe server cu React, Node și Express
- Note despre accesibilitatea redată de client
Redux a fost creat de Dan Abramov în jurul lunii iunie 2015. A fost inspirat de Flux de la Facebook și limbajul de programare funcțional Elm. Redux a devenit popular foarte repede datorită simplității , dimensiunii mici (doar 2 KB) și documentației excelente. Dacă doriți să aflați cum funcționează Redux în interior și să vă scufundați adânc în bibliotecă, luați în considerare cursul gratuit al lui Dan.
Redux este folosit mai ales pentru gestionarea stării aplicației. Pentru a rezuma, Redux menține starea unei întregi aplicații într-un singur arbore de stări imuabil (obiect), care nu poate fi schimbat direct. Când ceva se schimbă, este creat un nou obiect (folosind acțiuni și reductoare). Vom trece peste conceptele de bază în detaliu mai jos.
Cum este diferit de MVC și Flux?
Pentru a oferi o perspectivă, să luăm modelul clasic model-view-controller (MVC), deoarece majoritatea dezvoltatorilor sunt familiarizați cu el. În arhitectura MVC, există o separare clară între date (model), prezentare (vizualizare) și logică (controller). Există o problemă cu aceasta, în special în aplicațiile la scară largă: fluxul de date este bidirecțional. Aceasta înseamnă că o singură modificare (o intrare de utilizator sau un răspuns API) poate afecta starea unei aplicații în multe locuri din cod - de exemplu, legarea de date în două sensuri. Poate fi greu de întreținut și de depanat.
Flux este foarte asemănător cu Redux. Principala diferență este că Flux are mai multe magazine care modifică starea aplicației și transmite aceste modificări ca evenimente. Componentele se pot abona la aceste evenimente pentru a se sincroniza cu starea curentă. Redux nu are un dispecer , care în Flux este folosit pentru a difuza încărcături utile către apelurile inverse înregistrate. O altă diferență în Flux este că sunt disponibile multe soiuri, ceea ce creează o oarecare confuzie și inconsecvență.
Beneficiile Redux
S-ar putea să vă întrebați „De ce ar trebui să folosesc Redux?” Mare întrebare. Există câteva avantaje ale utilizării Redux în următoarea aplicație:
- Previzibilitatea rezultatului
Există întotdeauna o singură sursă de adevăr, magazinul, fără confuzie despre cum să sincronizați starea curentă cu acțiunile și alte părți ale aplicației. - Mentenabilitatea
Având un rezultat previzibil și o structură strictă, codul este mai ușor de întreținut. - Organizare
Redux este mai strict în ceea ce privește modul în care ar trebui să fie organizat codul, ceea ce face codul mai consistent și mai ușor de lucrat pentru o echipă. - Redare server
Acest lucru este foarte util, mai ales pentru randarea inițială, ceea ce face pentru o experiență mai bună pentru utilizator sau pentru optimizarea motorului de căutare. Doar treceți magazinul creat pe server către partea clientului. - Instrumente de dezvoltare
Dezvoltatorii pot urmări tot ce se întâmplă în aplicație în timp real, de la acțiuni la modificări de stare. - Comunitate și ecosistem
Acesta este un plus uriaș ori de câte ori învățați sau utilizați orice bibliotecă sau cadru. Având o comunitate în spatele Redux, îl face și mai atrăgător de utilizat. - Ușurință de testare
Prima regulă de scriere a codului testabil este să scrieți funcții mici care fac un singur lucru și care sunt independente. Codul Redux este în mare parte funcții care sunt doar atât: mici, pure și izolate.
Programare functionala
După cum am menționat, Redux a fost construit pe baza conceptelor de programare funcțională. Înțelegerea acestor concepte este foarte importantă pentru a înțelege cum și de ce Redux funcționează așa cum o face. Să trecem în revistă conceptele fundamentale ale programării funcționale:
- Este capabil să trateze funcțiile ca obiecte de primă clasă.
- Este capabil să transmită funcții ca argumente.
- Este capabil să controleze fluxul folosind funcții, recursiuni și matrice.
- Este capabil să utilizeze funcții pure, recursive, de ordin superior, de închidere și anonime.
- Este capabil să utilizeze funcții de ajutor, cum ar fi harta, filtrarea și reducerea.
- Este capabil să înlănțuiască funcțiile împreună.
- Statul nu se schimbă (adică este imuabil).
- Ordinea executării codului nu este importantă.
Programarea funcțională ne permite să scriem cod mai curat și mai modular. Prin scrierea unor funcții mai mici și mai simple, care sunt izolate în domeniul de aplicare și logică, putem face codul mult mai ușor de testat, întreținut și depanat. Acum aceste funcții mai mici devin cod reutilizabil și asta vă permite să scrieți mai puțin cod, iar mai puțin cod este un lucru bun. Funcțiile pot fi copiate și lipite oriunde fără nicio modificare. Funcțiile care sunt izolate în domeniu și care îndeplinesc o singură sarcină vor depinde mai puțin de alte module dintr-o aplicație, iar această cuplare redusă este un alt beneficiu al programării funcționale.

Veți vedea funcții pure, funcții anonime, închideri, funcții de ordin superior și lanțuri de metode, printre altele, foarte des atunci când lucrați cu JavaScript funcțional. Redux folosește foarte mult funcții pure, așa că este important să înțelegeți care sunt acestea.
Funcțiile pure returnează o nouă valoare bazată pe argumentele transmise acestora. Ele nu modifică obiectele existente; în schimb, returnează unul nou. Aceste funcții nu se bazează pe starea din care sunt apelate și returnează doar unul și același rezultat pentru orice argument furnizat. Din acest motiv, ele sunt foarte previzibile.
Deoarece funcțiile pure nu modifică nicio valoare, ele nu au niciun impact asupra domeniului de aplicare sau efecte secundare observabile și asta înseamnă că un dezvoltator se poate concentra doar pe valorile pe care funcția pură le returnează.
Unde poate fi folosit Redux?
Majoritatea dezvoltatorilor asociază Redux cu React, dar poate fi folosit cu orice altă bibliotecă de vizualizare. De exemplu, puteți utiliza Redux cu AngularJS, Vue.js, Polymer, Ember, Backbone.js și Meteor. Redux plus React este totuși cea mai comună combinație. Asigurați-vă că învățați React în ordinea corectă: cel mai bun ghid este cel al lui Pete Hunt, care este foarte util pentru dezvoltatorii care încep cu React și sunt copleșiți de tot ce se întâmplă în ecosistem. Oboseala JavaScript este o preocupare legitimă în rândul dezvoltatorilor front-end, atât noi, cât și cu experiență, așa că fă-ți timp pentru a învăța React sau Redux în modul corect, în ordinea corectă.
Unul dintre motivele pentru care Redux este minunat este ecosistemul său. Sunt disponibile atât de multe articole, tutoriale, middleware, instrumente și boilerplate. Personal, folosesc boilerplate lui David Zukowski pentru că are tot ce este necesar pentru a construi o aplicație JavaScript, cu React, Redux și React Router. Un cuvânt de precauție: Încercați să nu utilizați boilerplate și kituri de pornire atunci când învățați cadre noi, cum ar fi React și Redux. O va face și mai confuză, pentru că nu vei înțelege cum funcționează totul împreună. Învață-l mai întâi și construiește o aplicație foarte simplă, în mod ideal ca proiect secundar, apoi folosește boilerplate pentru aplicațiile de producție pentru a economisi timp.
Părți de construcție ale Redux
Conceptele Redux ar putea suna complicate sau fanteziste, dar sunt simple. Amintiți-vă că biblioteca are doar 2 KB. Redux are trei părți de construcție: acțiuni, magazin și reductoare.

Să discutăm ce face fiecare.

Acțiuni
Pe scurt, acțiunile sunt evenimente. Acțiunile trimit date din aplicație (interacțiuni cu utilizatorul, evenimente interne, cum ar fi apeluri API și trimiteri de formulare) către magazin. Magazinul obține informații numai din acțiuni. Acțiunile interne sunt obiecte JavaScript simple care au o proprietate de type
(de obicei constantă), care descrie tipul de acțiune și încărcătura utilă de informații trimise către magazin.
{ type: LOGIN_FORM_SUBMIT, payload: {username: 'alex', password: '123456'} }
Acțiunile sunt create cu creatori de acțiuni. Sună evident, știu. Sunt doar funcții care returnează acțiuni.
function authUser(form) { return { type: LOGIN_FORM_SUBMIT, payload: form } }
Apelarea acțiunilor oriunde în aplicație este, prin urmare, foarte ușoară. Utilizați metoda de dispatch
, astfel:
dispatch(authUser(form));
Reductoare
Am discutat deja ce este un reductor în JavaScript funcțional. Se bazează pe metoda de reducere a matricei, în care acceptă un callback (reductor) și vă permite să obțineți o singură valoare din mai multe valori, sume de numere întregi sau o acumulare de fluxuri de valori. În Redux, reductoarele sunt funcții (pure) care preiau starea curentă a aplicației și o acțiune și apoi returnează o stare nouă. Înțelegerea modului în care funcționează reductoarele este importantă, deoarece efectuează cea mai mare parte a muncii. Iată un reductor foarte simplu care ia starea curentă și o acțiune ca argumente și apoi returnează următoarea stare:
function handleAuth(state, action) { return _.assign({}, state, { auth: action.payload }); }
Pentru aplicații mai complexe, utilizarea utilitarului combineReducers()
oferit de Redux este posibilă (într-adevăr, recomandată). Combină toate reductoarele din aplicație într-un singur reductor de index. Fiecare reductor este responsabil pentru propria sa parte din starea aplicației, iar parametrul de stare este diferit pentru fiecare reductor. combineReducers()
face structura fișierelor mult mai ușor de întreținut.
Dacă un obiect (stare) modifică doar unele valori, Redux creează un nou obiect, valorile care nu s-au schimbat se vor referi la obiectul vechi și vor fi create numai valori noi. Este grozav pentru performanță. Pentru a-l face și mai eficient, puteți adăuga Immutable.js.
const rootReducer = combineReducers({ handleAuth: handleAuth, editProfile: editProfile, changePassword: changePassword });
Magazin
Store este obiectul care deține starea aplicației și oferă câteva metode de ajutor pentru a accesa starea, a trimite acțiuni și a înregistra ascultătorii. Întregul stat este reprezentat de un singur magazin. Orice acțiune returnează o nouă stare prin reductoare. Acest lucru face ca Redux să fie foarte simplu și previzibil.
import { createStore } from 'redux'; let store = createStore(rootReducer); let authInfo = {username: 'alex', password: '123456'}; store.dispatch(authUser(authInfo));
Instrumente pentru dezvoltatori, călătorie în timp și reîncărcare la cald
Pentru a face mai ușor să lucrați cu Redux, mai ales când lucrați cu o aplicație la scară largă, vă recomand să utilizați Redux DevTools. Este incredibil de util, arătând schimbările statului în timp, schimbările în timp real, acțiunile și starea actuală. Acest lucru vă economisește timp și efort, evitând starea și acțiunile actuale console.log

Redux are o implementare ușor diferită a călătoriei în timp decât Flux. În Redux, puteți reveni la o stare anterioară și chiar vă puteți duce starea într-o direcție diferită din acel moment. Redux DevTools acceptă următoarele caracteristici de „călătorie în timp” în fluxul de lucru Redux (gândiți-vă la ele ca comenzi Git pentru starea dvs.):
- Resetare : resetează la starea în care a fost creat magazinul dvs
- Revenire : revine la ultima stare comisă
- Sweep : elimină toate acțiunile dezactivate pe care le-ați putea declanșa din greșeală
- Commit : face din starea curentă starea inițială
Caracteristica de călătorie în timp nu este eficientă în producție și este destinată doar dezvoltării și depanării. Același lucru este valabil și pentru DevTools.
Redux face testarea mult mai ușoară, deoarece folosește JavaScript funcțional ca bază, iar funcțiile independente mici sunt ușor de testat. Deci, dacă trebuie să schimbați ceva în arborele de stare, importați un singur reductor care este responsabil pentru acea stare și testați-l izolat.
Creați o aplicație
Pentru a încheia acest ghid introductiv, să construim o aplicație foarte simplă folosind Redux și React. Pentru a fi mai ușor de urmărit pentru toată lumea, voi rămâne la JavaScript vechi simplu, folosind ECMAScript 2015 și 2016 cât mai puțin posibil. Vom continua logica de conectare începută mai devreme în această postare. Acest exemplu nu folosește date live, deoarece scopul acestei aplicații este de a arăta modul în care Redux gestionează starea unei aplicații foarte simple. Vom folosi CodePen.
1. Componenta React
Avem nevoie de câteva componente și date React. Să facem o componentă simplă și să o redăm pe pagină. Componenta va avea un câmp de introducere și un buton (este un formular de autentificare foarte simplu). Mai jos, vom adăuga text care reprezintă starea noastră:
Vedeți introducerea Pen pentru Redux de Alex Bachuk (@abachuk) pe CodePen.
2. Evenimente și acțiuni
Să adăugăm Redux la proiect și să gestionăm evenimentul onClick
pentru butonul. Imediat ce utilizatorul se conectează, vom trimite acțiunea cu tipul LOGIN
și valoarea utilizatorului curent. Înainte de a putea face asta, trebuie să creăm un magazin și să îi transmitem o funcție de reducere ca argument. Deocamdată, reductorul va fi doar o funcție goală:
Vedeți Pen Intro to Redux - Pasul 2. Evenimente și acțiuni de Alex Bachuk (@abachuk) pe CodePen.
3. Reductoare
Acum că avem acțiunea de declanșare, reductorul va lua acea acțiune și va returna o nouă stare. Să ne ocupăm de acțiunea LOGIN
returnând o stare de autentificare și, de asemenea, să adăugăm o acțiune LOGOUT
, astfel încât să o putem folosi mai târziu. Reductorul de auth
acceptă doi parametri:
- starea curentă (care are valoarea implicită),
- actiunea.
Vedeți Pen Intro to Redux - Pasul 3. Reducere de Alex Bachuk (@abachuk) pe CodePen.
4. Afișarea stării curente
Acum, că avem starea inițială (valoarea implicită în reductor) și componenta React gata, să vedem cum arată starea. O bună practică este de a împinge statul la componentele copiilor. Deoarece avem o singură componentă, să transmitem starea aplicației ca proprietate pentru auth
componentelor. Pentru a face totul să funcționeze împreună, trebuie să înregistrăm ascultătorul magazinului cu o metodă de ajutor de subscribe
, prin împachetarea ReactDOM.render
într-o funcție și pasând-o la store.subscribe()
:
Vedeți Pen Intro to Redux - Pasul 4. Afișarea stării curente de Alex Bachuk (@abachuk) pe CodePen.
5. Conectare și deconectare
Acum că avem gestionatori de acțiuni de conectare și deconectare, să adăugăm un buton de deconectare și să trimitem acțiunea LOGOUT
. Ultimul pas este să gestionați ce buton să afișați conectarea sau deconectarea, mutând această conectare în afara metodei de randare și redând variabila mai jos:
Vedeți Pen Intro to Redux - Pasul 5. Conectați-vă/Deconectați de Alex Bachuk (@abachuk) pe CodePen.
Concluzie
Redux câștigă teren în fiecare zi. A fost folosit de multe companii (Uber, Khan Academy, Twitter) și în multe proiecte (Apollo, WordPress' Calypso), cu succes în producție. Unii dezvoltatori s-ar putea plânge că există o mulțime de cheltuieli generale. În cele mai multe cazuri, este necesar mai mult cod pentru a efectua acțiuni simple, cum ar fi clicuri pe butoane sau modificări simple ale interfeței de utilizare. Redux nu se potrivește perfect pentru orice. Trebuie să existe un echilibru. Poate că acțiunile simple și modificările UI nu trebuie să facă parte din magazinul Redux și pot fi menținute la nivel de componentă.
Chiar dacă Redux ar putea să nu fie soluția ideală pentru aplicația sau cadrul dvs., vă recomand cu căldură să o verificați, în special pentru aplicațiile React.
Credite imagine pe prima pagină: Lynn Fisher, @lynnandtonic