Noțiuni de bază cu Redux De ce Redux?

Când învățați React, veți auzi aproape întotdeauna oamenii spunând cât de mare este Redux și că ar trebui să încercați. Ecosistemul React crește într-un ritm rapid și există atât de multe biblioteci pe care le puteți conecta cu React, cum ar fi flow, redux, middlewares, mobx etc.. 

Learning React este ușor, dar obișnuirea cu întregul ecosistem React necesită timp. Acest tutorial este o introducere la una din componentele integrate ale ecosistemului React-Redux.

Terminologie de bază non-Redux

Iată câteva dintre terminologiile utilizate în mod obișnuit, pe care probabil că nu le cunoașteți, dar nu sunt specifice pentru Redux în sine. Puteți trece prin această secțiune și vă puteți întoarce aici dacă / dacă ceva nu are sens.  

Funcția Pure

O funcție pură este doar o funcție normală, cu două constrângeri suplimentare pe care trebuie să le îndeplinească: 

  1. Dat fiind un set de intrări, funcția ar trebui să întoarcă întotdeauna aceeași ieșire. 
  2. Nu produce efecte secundare.

De exemplu, aici este o funcție pură care returnează suma a două numere.

/ * Funcția Pure add * / const adăugă = (x, y) => return x + y;  console.log (add (2,3)) // 5 

Funcțiile pure dau o ieșire previzibilă și sunt deterministe. O funcție devine impură când efectuează altceva decât calcularea valorii returnate. 

De exemplu, funcția de adăugare de mai jos utilizează o stare globală pentru a calcula rezultatele sale. În plus, funcția înregistrează, de asemenea, valoarea la consola, care este considerată a fi un efect secundar. 

const y = 10; const impureAdd = (x) => console.log ('Intrările sunt $ x și $ y'); retur x + y;  

Efecte secundare evidente

"Efecte secundare observabile" este un termen fantezist pentru interacțiunile făcute de o funcție cu lumea exterioară. Dacă o funcție încearcă să scrie o valoare într-o variabilă care există în afara funcției sau încearcă să apeleze o metodă externă, atunci puteți să apelați în siguranță aceste lucruri. 

Totuși, dacă o funcție pură numește o altă funcție pură, atunci funcția poate fi tratată ca pură. Iată câteva din reacțiile adverse frecvente:

  • efectuând apeluri API
  • înregistrarea în consola sau imprimarea datelor
  • date mutante
  • Manipularea DOM
  • preluarea timpului curent

Containere și componente de prezentare

Împărțirea arhitecturii componente în două este utilă în timpul lucrului cu aplicațiile React. Puteți să le clasificați pe larg în două categorii: componente de container și componente de prezentare. Ele sunt, de asemenea, cunoscut sub numele de componente inteligente și prost. 

Componenta containerului este preocupată de modul în care funcționează lucrurile, în timp ce componentele de prezentare se referă la modul în care arată lucrurile. Pentru a înțelege mai bine conceptele, am abordat acest lucru într-un alt tutorial: Componenta vs. Componentele Prezentare în React.

Obiecte mutabile vs. imuabile

Un obiect mutabil poate fi definit după cum urmează:

obiect mutabil este un obiect a cărui stare poate fi modificată după ce a fost creată.

Imutabilitatea este exact opusul - un obiect imuabil este un obiect a cărui stare nu poti fi modificat după ce a fost creat. În JavaScript, șirurile și numerele sunt imuabile, dar obiectele și matricele nu sunt. Exemplul demonstrează diferența mai bună. 

/ * Corzile și numerele sunt imuabile * / let a = 10; b = a; b = 3; console.log ('a = $ a și b = $ b'); // a = 10 și b = 3 / * Dar obiectele și matricele nu sunt * / / * Să începem cu obiectele * / let user = nume: "Bob", vârsta: 22, job: "None" active_user = user ; active_user.name = "Tim"; // Ambele obiecte au aceeași valoare console.log (active_user); // "nume": "Tim", "vârstă": 22, "job": "Niciuna" console.log (utilizator); // "nume": "Tim", "vârstă": 22, "job": "Niciuna" / * Acum pentru array * / let usersId = [1,2,3,4,5] let usersIdDup = ; usersIdDup.pop (); console.log (usersIdDup); // [1,2,3,4] console.log (utilizatoriId); // [1,2,3,4]

Pentru a face obiectele imuabile, utilizați Object.assign metoda de a crea o nouă metodă sau tot noul operator de răspândire.

permite utilizatorului = name: "Bob", vârsta: 22, job: "None" active_user = Object.assign (, user, name: "Tim") console.log; // "nume": "Bob", "vârstă": 22, "job": "None" console.log (active_user); //  "name": "Tim", "vârstă": 22, "locuri de muncă": "Nici unul" 

Ce este Redux?

Pagina oficială definește Redux după cum urmează:

Redux este un container de stare previzibil pentru aplicațiile JavaScript. 

Deși acest lucru descrie cu exactitate Redux, este ușor să vă pierdeți atunci când vedeți pentru prima dată imaginea mai largă a lui Redux. Are atât de multe piese în mișcare pe care trebuie să le potriviți împreună. Dar, odată ce faci, îți promit că vei începe să-i iubești pe Redux. 

Redux este o bibliotecă de management de stat pe care o puteți conecta cu orice bibliotecă JavaScript, și nu doar React. Cu toate acestea, funcționează foarte bine cu React din cauza naturii funcționale a React. Pentru a înțelege acest lucru mai bine, să aruncăm o privire la stat.

După cum puteți vedea, starea unei componente determină ce se preia și cum se comportă. Aplicația are o stare inițială, iar orice interacțiune a utilizatorului declanșează o acțiune care actualizează starea. Când starea este actualizată, pagina este reintrodusă.

Cu React, fiecare componentă are o stare locală accesibilă din interiorul componentei sau puteți să le transmiteți ca elemente de recuzită pentru componentele copilului. De obicei folosim statul pentru a stoca:

  1. Datele UI de stat și de tranziție. Aceasta include o listă de elemente UI pentru meniul de navigare sau intrările de formulare într-o componentă controlată.
  2. Starea aplicației, cum ar fi datele preluate de la un server, starea de conectare a utilizatorului etc..

Stocarea datelor de aplicație în starea unei componente este în regulă atunci când aveți o aplicație de bază React cu câteva componente. 

Ierarhia de componente a unei aplicații de bază

Cu toate acestea, majoritatea aplicațiilor din viața reală vor avea mult mai multe caracteristici și componente. Când crește numărul de nivele din ierarhia componentelor, gestionarea stării devine problematică. 

Schița unei aplicații de dimensiuni medii

De ce ar trebui să utilizați Redux?

Iată un scenariu foarte probabil pe care îl puteți întâlni în timp ce lucrați cu React.

  1. Construiți o aplicație de dimensiuni medii, iar componentele dvs. sunt împărțite în componente inteligente și proaste. 
  2. Componentele inteligente gestionează starea și le transmit apoi componentelor prost. Ei se ocupă de efectuarea apelurilor API, preluarea datelor din sursa de date, prelucrarea datelor și apoi setarea stării. Componentele proaste primesc recuzele și returnează reprezentarea UI. 
  3. Când sunteți pe punctul de a scrie o componentă nouă, nu este întotdeauna clar unde să plasați statul. Ați putea permite statului să facă parte dintr-un container care este un părinte imediat al componentei de prezentare. Mai bine, ați putea muta statul mai sus în ierarhie, astfel încât statul să fie accesibil mai multor componente de prezentare.
  4. Atunci când aplicația crește, veți vedea că statul este împrăștiat peste tot. Când o componentă are nevoie să acceseze starea în care nu are acces imediat, veți încerca să ridicați starea până la cel mai apropiat părinte. 
  5. După refactorizarea și curățarea constantă, veți termina cu majoritatea locurilor deținute de stat în partea de sus a ierarhiei componente. 
  6. În cele din urmă, decideți că este o idee bună să lăsați o componentă de la început să se ocupe de stat la nivel global și apoi să treacă totul jos. Fiecare altă componentă se poate abona la recuzita de care au nevoie și ignora restul.

Aceasta este ceea ce am experimentat personal cu React, și o mulțime de alți dezvoltatori vor fi de acord. React este o bibliotecă de vizualizare și nu este de datoria lui React să gestioneze în mod specific statul. Ceea ce căutăm este principiul separării preocupărilor. 

Redux vă ajută să separați starea aplicației de React. Redux creează un magazin global care se află la cel mai înalt nivel al aplicației dvs. și alimentează starea tuturor celorlalte componente. Spre deosebire de Flux, Redux nu are obiecte de stocare multiple. Întreaga stare a aplicației se află în acel obiect de stocare și ați putea să schimbați stratul vizual cu altă bibliotecă cu magazinul intact.

Componentele redeal de fiecare dată când magazinul este actualizat, cu un impact foarte mic asupra performanței. Asta este o veste bună, iar asta aduce și o mulțime de beneficii. Puteți trata toate componentele dvs. React ca fiind prost, iar React se poate concentra doar pe partea de vedere a lucrurilor.

Acum că știm de ce Redux este util, să ne aruncăm în arhitectura Redux.

Arhitectura Redux

Când învățați Redux, există câteva concepte de bază pe care trebuie să vă obișnuiți. Imaginea de mai jos descrie arhitectura Redux și modul în care totul este conectat împreună. 

Redux pe scurt

Dacă sunteți obișnuiți cu Flux, unele dintre ele ar putea părea familiare. Dacă nu, este bine și pentru că vom acoperi totul de la bază. Mai întâi, asigurați-vă că ați instalat redux:

npm install redux

Utilizați aplicația create-react-react sau configurația preferată a pachetului web pentru a configura serverul de dezvoltare. Din moment ce Redux este un management independent al statului, nu vom mai conecta încă React. Deci, eliminați conținutul index.js și vom juca cu Redux pentru restul tutorialului.

Magazin

Magazinul este un obiect JavaScript mare care are tone de perechi cheie-valoare care reprezintă starea curentă a aplicației. Spre deosebire de obiectul de stat din React, care este presărat pe diferite componente, avem doar un magazin. Magazinul oferă starea aplicației și, de fiecare dată când starea actualizează, vizualizarea redevine. 

in orice caz, nu puteți muta sau modifica magazinul. În schimb, creați noi versiuni ale magazinului. 

(precedentState, acțiune) => newState

Din acest motiv, puteți să călătoriți în timp prin toate statele din momentul în care aplicația a fost pornită în browserul dvs..

Magazinul are trei metode de comunicare cu restul arhitecturii. Sunt:

  • Store.getState () - Pentru a accesa arborele de stare curent al aplicației. 
  • Store.dispatch (action) - Pentru a declanșa o schimbare de stat bazată pe o acțiune. Mai multe despre acțiunile de mai jos.
  • Store.subscribe (ascultător) -Pentru a asculta orice schimbare în stare. Se va numi de fiecare dată când o acțiune este expediată.

Să creăm un magazin. Redux are a CreateStore pentru a crea un nou magazin. Trebuie să-i dați un reductor, deși nu știm ce înseamnă asta. Deci, voi crea doar o funcție numită reductor. Puteți specifica opțional un al doilea argument care stabilește starea inițială a magazinului. 

src / index.js

import createStore de la "redux"; // Acesta este reductorul const reducer = () => / * Ceva merge aici * / // initialState este opțional. // Pentru acest demo, folosesc un contor, dar de obicei statul este un obiect const constState = 0 const store = createStore (reductor, initialState);

Acum o să ascultăm orice schimbare în magazin și apoi console.log () starea actuală a magazinului.

store.subscribe (() => console.log ("Statul sa schimbat" + store.getState ());) 

Deci, cum actualizăm magazinul? Redux are ceva numit acțiuni care fac acest lucru să se întâmple.

Creatori de acțiuni / acțiuni

Acțiunile sunt, de asemenea, simple obiecte JavaScript care trimit informații din aplicația dvs. către magazin. Dacă aveți un contor foarte simplu cu un buton de incrementare, apăsarea acestuia va duce la declanșarea unei acțiuni care arată astfel:

tip: "INCREMENT", sarcina utila: 1

Ele sunt singura sursă de informație pentru magazin. Starea magazinului se modifică numai ca răspuns la o acțiune. Fiecare acțiune trebuie să aibă o proprietate de tip care descrie ce intenționează să facă obiectul de acțiune. În afară de asta, structura acțiunii este pe deplin la dvs. Cu toate acestea, păstrați acțiunea dvs. mică deoarece o acțiune reprezintă cantitatea minimă de informații necesare transformării stării aplicației. 

De exemplu, în exemplul de mai sus, proprietatea tip este setată la "INCREMENT" și este inclusă o proprietate suplimentară a încărcăturii utile. Ați putea să redenumiți proprietatea încărcăturii utile pentru ceva mai semnificativ sau, în cazul nostru, omiteți-o în întregime. Puteți expedia o acțiune la magazin ca asta.

store.dispatch (tip: "INCREMENT", sarcina utila: 1); 

În timp ce codificați Redux, nu veți folosi în mod normal acțiuni direct. În schimb, veți apela funcții care returnează acțiuni, iar aceste funcții sunt cunoscute popular ca creatori de acțiuni. Iată creatorul de acțiuni pentru acțiunea incrementală pe care am discutat-o ​​mai devreme.

const incrementCount = (număr) => return type: "INCREMENT", sarcină utilă: count

Deci, pentru a actualiza starea contorului, va trebui să expediați incrementCount acțiune ca aceasta:

store.dispatch (incrementCount (1)); store.dispatch (incrementCount (1)); store.dispatch (incrementCount (1));

Dacă vă îndreptați spre consola browserului, veți vedea că funcționează parțial. Ne găsim nedefiniți, deoarece nu am definit încă reductorul.

Deci, acum am acoperi acțiunile și magazinul. Cu toate acestea, avem nevoie de un mecanism pentru a converti informațiile furnizate de acțiune și pentru a transforma starea magazinului. Reductoarele servesc acestui scop.

Reductore

O acțiune descrie problema, iar reductorul este responsabil pentru rezolvarea problemei. În exemplul anterior, incrementCount metoda a returnat o acțiune care a furnizat informații despre tipul de schimbare pe care am dorit să o facem statului. Reducătorul folosește aceste informații pentru a actualiza efectiv starea. Există un punct important evidențiat în documentele pe care trebuie să le rețineți întotdeauna în timp ce utilizați Redux:

Având aceleași argumente, un Reducător ar trebui să calculeze următoarea stare și să o returneze. Nicio surpriza. Fără efecte secundare. Nu există apeluri API. Nu există mutații. Doar un calcul.

Ce înseamnă acest reductor ar trebui să fie o funcție pură. Având un set de intrări, acesta ar trebui să întoarcă întotdeauna aceeași ieșire. Dincolo de asta, nu ar trebui să mai facă nimic. De asemenea, un reductor nu este locul pentru efecte secundare, cum ar fi efectuarea de apeluri AJAX sau preluarea datelor din API. 

Să umplem reductorul pentru contorul nostru.

// Aceasta este reductorul const reductor = (state = initialState, action) => comutare (action.type) caz "INCREMENT": stare de returnare + action.payload default: return state

Reductorul acceptă două argumente - stare și acțiune - și readuce o stare nouă.

(precedentState, acțiune) => newState

Statul acceptă o valoare implicită, stare initiala, care vor fi utilizate numai dacă valoarea statului este nedefinită. În caz contrar, valoarea reală a statului va fi reținută. Utilizăm instrucțiunea comutator pentru a selecta acțiunea potrivită. Reîmprospătați browserul și totul funcționează conform așteptărilor. 

Să adăugăm un caz pentru Decrementați, fără de care contorul este incomplet.

// Aceasta este reducere const reducer = (state = initialState, action) => comutare (action.type) caz "INCREMENT": stare returnare + action.payload caz "DECREMENT": return status - action.payload default: retur stație

Iată creatorul de acțiuni.

const decrementCount = (count) => return type: "DECREMENT", sarcina utila: count

În cele din urmă, expediați-l la magazin.

store.dispatch (incrementCount (4)); // 4 store.dispatch (decrementCount (2)); // 2

Asta e!

rezumat

Acest tutorial a fost menit să fie un punct de plecare pentru administrarea statului cu Redux. Am acoperit tot ceea ce este esențial pentru a înțelege conceptele de bază Redux, cum ar fi magazinul, acțiunile și reducerile. Spre sfârșitul tutorialului, am creat și un demo de lucru redux de lucru. Deși nu a fost prea mult, am aflat cum se potrivesc toate piesele puzzle-ului. 

În ultimii ani, React a crescut în popularitate. De fapt, avem un număr de elemente pe piață care sunt disponibile pentru cumpărare, revizuire, implementare și așa mai departe. Dacă sunteți în căutarea unor resurse suplimentare în jurul React, nu ezitați să le verificați.

În tutorialul următor, vom face uz de lucrurile pe care le-am învățat aici pentru a crea o aplicație React folosind Redux. Rămâi acordat până atunci. Împărtășiți-vă gândurile în comentariile. 

Cod