Noțiuni de bază cu Redux Conectarea Redux cu React

Aceasta este a treia parte a seriei despre Începerea cu Redux și în acest tutorial vom învăța cum să conectăm un magazin Redux cu React. Redux este o bibliotecă independentă, care funcționează cu toate bibliotecile și cadrele populare. Și funcționează perfect cu React datorită abordării sale funcționale.

Nu trebuie să fi urmat părțile anterioare ale acestei serii pentru ca acest tutorial să aibă sens. Dacă sunteți aici pentru a afla despre utilizarea lui React cu Redux, puteți face recuperarea rapidă mai jos și apoi verificați codul din partea anterioară și începeți de acolo. 

Recapitulare rapidă

În primul post, am aflat despre fluxul de lucru Redux și am răspuns la întrebare, De ce Redux? Am creat o aplicație demo de bază și ne-a arătat cum sunt conectate diferitele componente ale Redux-acțiuni, reductoare și magazin.

În postarea precedentă, am început să construim o aplicație din lista de contacte care vă permite să adăugați contacte și apoi să le afișați ca listă. Am creat un magazin Redux pentru lista noastră de contacte și am adăugat câteva reduceri și acțiuni. Am încercat să expediem acțiunile și să recuperăm noul stat folosind metode de stocare cum ar fi store.dispatch () și store.getState ().

Până la sfârșitul acestui articol, veți fi învățat:

  1. diferența dintre componentele containerului și componentele de prezentare
  2. despre biblioteca react-redux
  3. cum se leagă reacția și reduxul folosind conectați()
  4. modul de expediere a acțiunilor utilizând mapDispatchToProps
  5. cum să recuperați utilizarea de stat mapStateToProps

Codul tutorialului este disponibil pe GitHub în repo reac-redux-demo. Prindeți codul din v2 ramura și folosiți-o ca punct de plecare pentru acest tutorial. Dacă sunteți curios să știți cum arată aplicația până la sfârșitul acestui tutorial, încercați sucursala v3. Să începem.

Proiectarea unei ierarhii de componente: Componente inteligente vs.

Acesta este un concept pe care probabil că ați auzit-o, dar să aruncăm o privire rapidă asupra diferenței dintre componentele inteligente și cele proaste. Amintiți-vă că am creat două directoare separate pentru componente, unul numit containere / si celalalt componente/. Beneficiul acestei abordări este că logica comportamentului este separată de vedere.

Componentele de prezentare se spune că sunt prost, deoarece sunt preocupați de modul în care arată lucrurile. Acestea sunt decuplate de logica de afaceri a aplicației și primesc date și apeluri de la o componentă părinte exclusiv prin recuzită. Nu le pasă dacă aplicația dvs. este conectată la un magazin Redux dacă datele provin din starea locală a componentei părinte. 

Componentele containerului, pe de altă parte, se ocupă de partea comportamentală și ar trebui să conțină o marcare și stil foarte limitat DOM. Ei trec datele care trebuie să fie redate componentelor prost ca elemente de recuzită. 

Am abordat subiectul în profunzime într-un alt tutorial, Componente Stateful vs. Stateless în React.

Mergând mai departe, să vedem cum vom organiza componentele noastre.

Componentele de prezentare

Iată componentele de prezentare pe care le vom folosi în acest tutorial. 

Componente / AddContactForm.jsx

import Reacționează de la "reacționează"; const AdaugăContactForm = (onInputChange, onFormSubmit) => ( 
/ * Unele coduri au fost omise pentru scurtă durată * /
) implicit pentru export AddContactForm;

Acesta este un formular HTML pentru adăugarea unui contact nou. Componenta primește onInputChange și onFormSubmit apeluri ca recuzită. onInputChange evenimentul este declanșat atunci când valoarea de intrare se modifică și onFormSubmit atunci când formularul este depus.

Componente / ContactList.jsx

const ContactList = (recuzită) => return ( 
    props.contactList.map ((contact) =>
  • )
) export implicit ContactList;

Această componentă primește o serie de obiecte de contact ca elemente de recuzită, de unde și numele Listă de contacte. Noi folosim Array.map () pentru a extrage detaliile individuale de contact și apoi a le transmite aceste date .

Componente / ContactCard.jsx

const ContactCard = (contact) => return ( 
contact.photo! == undefined ? contact.name : contact.name
contact.name + "+ contact.surname
/ * Unele coduri au fost omise pentru scurtă durată * /
) cartelă de contact implicită pentru export;

Această componentă primește un obiect de contact și afișează numele și imaginea contactului. Pentru aplicații practice, ar putea fi logic să găzduiți imagini JavaScript în cloud.

Componente pentru containere

Vom construi, de asemenea, componente de rezervoare pentru oase goale.

containere / Contacts.jsx

clasa Contacts extinde Component constructor (recuzită) super (recuzită); this.returnContactList = this.returnContactList.bind (acest);  returnContactList () // Retrieve lista de contacte din magazin render () return ( 

); export implicit Contacte;

returnContactList () funcția recuperează matricea de obiecte de contact și o transmite către componenta ContactList. De cand returnContactList () preia datele din magazin, vom lăsa acea logică pentru moment.

containere / AddContacts.jsx

clasa AddContact extinde Component constructor (recuzită) super (recuzită); / * Legarea funcției merge aici. Omis pentru scurtătate * / showAddContactBox () / * Logic pentru comutarea contactuluiFormul * / handleInputChange (eveniment) const target = event.target; const valoare = target.value; const nume = target.name; / * Logică pentru manipularea Schimbare intrare * / handleSubmit (e) e.preventDefault (); / * Logic pentru ascunderea formularului și actualizarea stării * / / * Refacerea AddContactForm * / renderForm () return ( 
render () retur (
/ * O declarație condiționată merge aici pentru a verifica dacă formularul trebuie afișat sau nu * /
) export implicit AddContact;

Am creat trei metode de manipulare a oaselor goale care corespund celor trei acțiuni. Toate acestea trimit acțiuni pentru a actualiza statul. În metoda rendering, am lăsat logica pentru a afișa / ascunde formularul deoarece trebuie să preluăm starea. 

Acum, să vedem cum să legem să reacționăm și să reducem împreună

Biblioteca react-redux

Reacția de legare nu este disponibilă în mod implicit în Redux. Va trebui să instalați mai întâi o bibliotecă suplimentară numită react-redux. 

npm instalează -save reac-redux 

Biblioteca exportă doar două API-uri pe care trebuie să le rețineți, a componentă și o funcție de ordin superior denumită conectați()

Componenta furnizor

Bibliotecile ca Redux trebuie să facă datele magazinului accesibile întregului arbore al componentelor React, pornind de la componenta rădăcină. Modelul furnizorului permite bibliotecii să transmită datele de sus în jos. Codul de mai jos demonstrează modul în care Provider adaugă magic starea la toate componentele din arborele componente. 

Codul demo

import Provider de la "react-redux" ReactDOM.render (   , document.getElementById ("rădăcină"))

Întreaga aplicație trebuie să aibă acces la magazin. Deci, înfășurăm furnizorul în jurul componentei aplicației și apoi adăugăm datele de care avem nevoie în contextul copacului. Descendenții componentei au apoi acces la date. 

conectați() Metodă 

Acum ce am făcut prevăzut magazinul pentru aplicația noastră, trebuie să conectăm React la magazin. Singura modalitate prin care puteți comunica cu magazinul este prin dispecerizarea acțiunilor și prin recuperarea stării. Am folosit anterior store.dispatch () să trimită acțiuni și store.getState () pentru a prelua cel mai recent instantaneu al statului. conectați() vă permite să faceți exact acest lucru, dar cu ajutorul a două metode cunoscute sub numele de mapDispatchToProps și mapStateToProps. Am demonstrat acest concept în exemplul de mai jos:

Codul demo

import connect de la "react-redux" const AddContact = (newContact, addContact) => return ( 
NewContact.name
NewContact.email
NewContact.phone
Sigur doriți să adăugați această persoană de contact? da
) const mapStateToProps = state => return newContact: state.contacts.newContact const mapDispatchToProps = dispatch => returnContact () )(Adaugă contact)

mapStateToProps și mapDispatchToProps ambele returnează un obiect, iar cheia acestui obiect devine un suport al componentei conectate. De exemplu, state.contacts.newContact este mapat la props.newContact. Creatorul acțiunii adaugă contact() este mapat la props.addContact.  

Dar pentru ca aceasta să funcționeze, aveți nevoie de ultima linie din fragmentul de cod de mai sus. 

conectare implicită la export (mapStateToProps, mapDispatchToProps) (AddContact)

În loc să exportați Adaugă contact componente direct, exportem o componentă conectată. Conexiunea asigură adaugă contact și contact nou ca elemente de recuzită la component. 

Cum se conectează React și Redux

Apoi, vom acoperi pașii care trebuie urmați pentru a conecta React și Redux.

Instalați Biblioteca react-redux

Instalați biblioteca react-redux dacă nu ați făcut-o deja. Puteți folosi NPM sau fire pentru ao instala. 

npm instalează react-redux - salvează 

Furnizați componenta App Store pentru aplicația dvs.

Creați mai întâi magazinul. Apoi, face obiectul magazinului accesibil copacului dvs. component, trecând-l ca pe o propunere .

index.js

import Reacționează de la "reacționează"; import render de la "react-dom"; import Provider de la aplicația "react-redux" de import din './App'; import configuraStore din './store' const store = configureStore (); face(   , document.getElementById ("rădăcină"))

Conectați Contactorii Reactați la Redux

Funcția de conectare este utilizată pentru a lega containerele React la Redux. Ceea ce înseamnă că poți folosi funcția de conectare la:

  1. abonați-vă la magazin și cartografiați-i starea la recuzită
  2. trimiteți acțiuni și cartografiați apelurile de expediere în recuzită

Odată ce ați conectat aplicația la Redux, puteți utiliza this.props pentru a accesa starea actuală și, de asemenea, pentru a trimite acțiuni. Voi demonstra acest proces pe Adaugă contact component. Adaugă contact trebuie să trimită trei acțiuni și să obțină starea a două proprietăți din magazin. Să ne uităm la cod.

Mai întâi, importă conectați în AddContact.jsx.

import connect de la "react-redux"; 

În al doilea rând, creați două metode: mapStateToProps și mapDispatchToProps.

funcția mapStateToProps (state) return isHidden: state.ui.isAddContactFormHidden, newContact: state.contacts.newContact maparea funcțieiDispatchToProps (expediere) return onFormSubmit: (newContact) => dispatch (addContact (newContact)); , onInputChange: (nume, valoare) => expediere (handleInputChange (nume, valoare)); , onToggle: () => expediere (toggleContactForm ()); 

mapStateToProps primește starea magazinului ca argument. Acesta returnează un obiect care descrie modul în care starea magazinului este mapată în recuzita. mapDispatchToProps returnează un obiect similar care descrie modul în care acțiunile de expediere sunt cartografiate la recuzita. 

În cele din urmă, vom folosi conectați pentru a lega Adaugă contact componenta la cele două funcții, după cum urmează:

conectare implicită la export (mapStateToProps, mapDispatchToProps) (AddContact) 

Actualizați componentele containerului pentru a utiliza elemente de recuzită

Componentele de recuzită sunt acum echipate pentru a citi starea din acțiunile de stocare și expediere. Logica pentru handeInputChange, handleSubmit și showAddContactBox ar trebui actualizate după cum urmează:

 showAddContactBox () const onToggle = this.props; onToggle ();  handleInputChange (eveniment) const țintă = event.target; const valoare = target.value; const nume = target.name; const onInputChange = this.props; onInputChange (nume, valoare);  handleSubmit (e) e.preventDefault (); this.props.onToggle (); this.props.onFormSubmit (); 

Am definit metodele de manipulare, dar încă lipsește o parte - instrucțiunea condiționată din interiorul face funcţie.

render () return ( 
this.props.isHidden === false? this.renderForm ():
)

Dacă este ascuns este falsă, forma este redată. În caz contrar, un buton devine redat. 

Afișarea Contactelor

Am terminat partea cea mai provocatoare. Acum, tot ce rămâne este să afișați aceste contacte ca o listă. Contacte containerul este cel mai bun loc pentru această logică. 

import React, Component de la "reacție"; import connect de la "react-redux"; / * Importul componentelor omis pentru scurtătate * / clasa Contactul extinde Component constructor (recuzită) super (recuzită); this.returnContactList = this.returnContactList.bind (acest);  returnContactList () return this.props.contactList;  render () return ( 


); functie mapStateToProps (state) retur contactList: state.contacts.contactList, export implicit connect (mapStateToProps, null) (Contact);

Am trecut prin aceeași procedură pe care am urmat-o mai sus pentru a conecta componenta Contacte cu magazinul Redux. mapStateToProps funcție hartă obiectul de stocare la listă de contacte recuzită. Apoi utilizăm conectarea pentru a lega valoarea de recuzită la componenta Contact. Al doilea argument pentru conectare este nul, deoarece nu avem nicio acțiune care să fie trimisă. Aceasta completează integrarea aplicației noastre cu starea magazinului Redux. 

Ce urmează?

În următoarea postare vom examina mai profund modulul middleware și vom începe acțiunile de dispecerizare care implică preluarea datelor de pe server. Împărtășiți-vă gândurile în comentariile!

Cod