Komma igång med Redux Anslut Redux med React

Det här är den tredje delen av serien om Komma igång med Redux, och i denna handledning kommer vi att lära oss hur du ansluter en Redux-butik med React. Redux är ett oberoende bibliotek som arbetar med alla populära front-end-bibliotek och ramverk. Och det fungerar felfritt med React på grund av dess funktionella inställning.

Du behöver inte följa de tidigare delarna av den här serien för att denna handledning ska vara meningsfull. Om du är här för att lära dig mer om att använda React with Redux, kan du ta snabbinspelningen nedan och kolla sedan koden från föregående del och börja därifrån. 

Snabbinspelning

I det första inlägget lärde vi oss om Redux-arbetsflödet och besvarade frågan, Varför Redux? Vi skapade en mycket grundläggande demo-applikation och visade dig hur de olika komponenterna i Redux-åtgärder, reducerare och butiken är anslutna.

I det föregående inlägget började vi bygga en kontaktlista applikation som låter dig lägga till kontakter och visar dem som en lista. Vi skapade en Redux butik för vår kontaktlista, och vi lade till några reducerare och åtgärder. Vi försökte skicka åtgärder och hämta den nya staten med hjälp av affärsmetoder som store.dispatch () och store.getState ().

I slutet av den här artikeln har du lärt dig:

  1. skillnaden mellan behållarkomponenter och presentationsdelar
  2. om reagens-redux-biblioteket
  3. hur man binder reagera och reducerar med ansluta()
  4. hur man skickar åtgärder med hjälp av mapDispatchToProps
  5. hur man hämtar tillstånd med mapStateToProps

Koden för handledningen finns tillgänglig på GitHub i React-Redux-Demo Repo. Ta tag i koden från v2 gren och använd det som utgångspunkt för denna handledning. Om du är nyfiken på hur applikationen ser ut i slutet av denna handledning, försök v3-avdelningen. Låt oss börja.

Designa en komponenthierarki: Smart vs Dumb Components

Det här är ett koncept som du förmodligen har hört talas om förut, men låt oss snabbt titta på skillnaden mellan smarta och dumma komponenter. Kom ihåg att vi skapade två separata kataloger för komponenter, en namngiven containrar / och den andra komponenter/. Fördelen med detta tillvägagångssätt är att beteendelogiken skiljs från vyn.

De presenterande komponenterna sägs vara dumma eftersom de är oroliga över hur sakerna ser ut. De kopplas bort från programmets logik och tar emot data och återkopplingar från en föräldrakomponent uteslutande via rekvisita. De bryr sig inte om din ansökan är ansluten till en Redux-butik om data kommer från den lokala delstaten av moderkomponenten. 

Behållarkomponenterna å andra sidan handlar om beteendedelen och bör innehålla mycket begränsad DOM-markup och stil. De skickar de data som behöver göras till de dumma komponenterna som rekvisita. 

Jag har täckt ämnet i djupet i en annan handledning, Stateful vs Stateless Components in React.

Fortsätt, se hur vi ska organisera våra komponenter.

Presentationskomponenter

Här är de presentationsdelar som vi ska använda i denna handledning. 

komponenter / AddContactForm.jsx

Import Reakt från "reagera"; const AddContactForm = (onInputChange, onFormSubmit) => ( 
/ * En del kod utelämnades för korthet * /
) export standard AddContactForm;

Det här är en HTML-form för att lägga till en ny kontakt. Komponenten tar emot onInputChange och onFormSubmit återuppringningar som rekvisita. De onInputChange händelse utlöses när ingångsvärdet ändras och onFormSubmit när formuläret lämnas in.

komponenter / ContactList.jsx

const ContactList = (rekvisita) => retur ( 
    props.contactList.map ((contact) =>
  • )
) exportera standard ContactList;

Denna komponent mottar en rad kontaktobjekt som rekvisita, därav namnet Kontaktlista. Vi använder Array.map () Metod för att extrahera enskilda kontaktuppgifter och vidarebefordra data till .

komponenter / ContactCard.jsx

const ContactCard = (contact) => returnera ( 
contact.photo! == undefined ? contact.name : contact.name
contact.name + "+ contact.surname
/ * En del kod utelämnades för korthet * /
) exportera standard ContactCard;

Den här komponenten tar emot ett kontaktobjekt och visar kontaktens namn och bild. För praktiska tillämpningar kan det vara bra att vara värd för JavaScript-bilder i molnet.

Containerkomponenter

Vi ska också konstruera behållarkomponenter med behållare.

behållare / Contacts.jsx

klasskontakter utökar komponent konstruktör (rekvisita) super (rekvisita); this.returnContactList = this.returnContactList.bind (this);  returnContactList () // Hämta kontaktlista från affären render () return ( 

); exportera standardkontakter;

De returnContactList () funktionen hämtar arrayen av kontaktobjekt och skickar den till ContactList-komponenten. Eftersom returnContactList () hämtar data från affären, lämnar vi det logiska blanket för tillfället.

behållare / AddContacts.jsx

klass AddContact utökar komponent konstruktör (rekvisita) super (rekvisita); / * Funktionsbindning går här. Utelämnades för korthet * / showAddContactBox () / * Logic för växling ContactForm * / handleInputChange (händelse) const target = event.target; const value = target.value; const name = target.name; / * Logik för hantering av Input Change * / handleSubmit (e) e.preventDefault (); / * Logik för att dölja formuläret och uppdatera tillståndet * / / * Ger AddContactForm * / renderForm () returnera ( 
) render () returnera (
/ * Ett villkorligt uttalande går här som kontrollerar om formuläret ska visas eller inte * /
) exportera standard AddContact;

Vi har skapat tre metoder för hantering av benmängder som motsvarar de tre åtgärderna. De skickar alla åtgärder för att uppdatera staten. I renderingsmetoden har vi utelämnat logiken för att visa / gömma formuläret eftersom vi behöver hämta tillståndet. 

Låt oss nu se hur man binder reagera och minska tillsammans

Reaktionsreduceringsbiblioteket

Reaktionsbindningar är inte tillgängliga i Redux som standard. Du måste installera ett extra bibliotek som kallas Reaktreducer först. 

npm installera - saves react-redux 

Biblioteket exporterar bara två API: er som du behöver komma ihåg, a komponent och en högre orderfunktion som kallas ansluta()

Leverantörskomponenten

Bibliotek som Redux behöver göra butiksdata tillgängliga för hela React-komponentträdet, från början av rotkomponenten. Leverantörsmönstret gör att biblioteket kan skicka data från topp till botten. Koden nedan visar hur leverantören matematiskt lägger till tillståndet för alla komponenter i komponentträdet. 

Demokod

importera Provider från 'react-redux' ReactDOM.render (   , document.getElementById ('root'))

Hela appen måste ha tillgång till affären. Så vi paketerar leverantören runt app-komponenten och lägger sedan till de data som vi behöver för trädets sammanhang. Komponternas efterkommande har tillgång till data. 

De ansluta() Metod 

Nu när vi har försedd butiken till vår ansökan, måste vi ansluta React till butiken. Det enda sättet du kan kommunicera med affären är att skicka handlingar och hämta staten. Vi har tidigare använt store.dispatch () att skicka åtgärder och store.getState () för att hämta den senaste snapshoten av staten. De ansluta() kan du göra exakt detta, men med hjälp av två metoder som kallas mapDispatchToProps och mapStateToProps. Jag har visat detta begrepp i exemplet nedan:

Demokod

importera connect från 'react-redux' const AddContact = (newContact, addContact) => returnera 
NewContact.name
NewContact.email
NewContact.phone
Är du säker på att du vill lägga till den här kontakten? Ja
) const mapStateToProps = state => return newContact: state.contacts.newContact const mapDispatchToProps = skicka => return addContact: () => skicka (addContact ()) exportera standardkoppling (mapStateToProps, mapDispatchToProps )(Lägg till kontakt)

mapStateToProps och mapDispatchToProps båda returnerar ett objekt, och nyckeln till det här objektet blir en prop av den anslutna komponenten. Till exempel, state.contacts.newContact är mappad till props.newContact. Åtgärdsskaparen Lägg till kontakt() är mappad till props.addContact.  

Men för att detta ska fungera behöver du den sista raden i kodfältet ovan. 

exportera standardkoppling (mapStateToProps, mapDispatchToProps) (AddContact)

I stället för att exportera Lägg till kontakt komponent direkt exporterar vi en ansluten komponent. Anslutningen ger Lägg till kontakt och ny kontakt som rekvisita till komponent. 

Så här ansluter du React och Redux

Därefter kommer vi att täcka de steg som du måste följa för att ansluta React och Redux.

Installera reaktorreduceringsbiblioteket

Installera Reaktor-Redux-biblioteket om du inte redan har det. Du kan använda NPM eller Garn för att installera det. 

npm installera reaktions-redux -save 

Ge butiken till din App-komponent

Skapa butiken först. Gör sedan affärsobjektet tillgängligt för ditt komponentträd genom att överföra det som ett försök till .

index.js

Import Reakt från "reagera"; importera render från 'react-dom'; importera Provider från "react-redux" importera App från "./App"; importera configureStore från './store' const store = configureStore (); göra(   , document.getElementById ('root'))

Anslut reaktionsbehållare till Redux

Anslutningsfunktionen används för att binda React containers till Redux. Vad det betyder är att du kan använda anslutningsfunktionen till:

  1. prenumerera på affären och kartlägga dess tillstånd till dina rekvisita
  2. sändningsåtgärder och kartlägga försändelsen återkoppling till dina rekvisita

När du har anslutit din ansökan till Redux kan du använda this.props för att få tillgång till nuvarande tillstånd och även för att skicka åtgärder. Jag ska demonstrera processen på Lägg till kontakt komponent. Lägg till kontakt måste skicka tre handlingar och få tillståndet för två fastigheter från affären. Låt oss ta en titt på koden.

Först importera ansluta in i AddContact.jsx.

importera connect från 'react-redux'; 

För det andra, skapa två metoder: mapStateToProps och mapDispatchToProps.

funktionskartaStateToProps (skick) return isHidden: state.ui.isAddContactFormHidden, newContact: state.contacts.newContact funktionskartaDispatchToProps (sändning) return onFormSubmit: (newContact) => sändning (addContact (newContact)); , onInputChange: (namn, värde) => sändning (handtagInputChange (namn, värde)); , onToggle: () => sändning (toggleContactForm ()); 

mapStateToProps mottar butiks tillstånd som argument. Det returnerar ett objekt som beskriver hur tillståndet i butiken är kartlagt i dina rekvisita. mapDispatchToProps returnerar ett liknande objekt som beskriver hur avsändningsåtgärderna är mappade till dina rekvisita. 

Slutligen använder vi ansluta att binda Lägg till kontakt komponent till de två funktionerna enligt följande:

exportera standardkoppling (mapStateToProps, mapDispatchToProps) (AddContact) 

Uppdatera behållarkomponenterna för att använda rekvisita

Komponentens rekvisita är nu utrustade för att läsa tillstånd från affären och leveransåtgärderna. Logiken för handeInputChange, handleSubmit och showAddContactBox bör uppdateras enligt följande:

 showAddContactBox () const onToggle = this.props; onToggle ();  handleInputChange (händelse) const target = event.target; const value = target.value; const name = target.name; const onInputChange = this.props; onInputChange (namn, värde);  hanteraSänd upp (e) e.preventDefault (); this.props.onToggle (); this.props.onFormSubmit (); 

Vi har definierat hanteringsmetoderna, men det finns fortfarande en del saknad - det villkorliga uttalandet inuti göra fungera.

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

Om är gömd är falskt, formuläret görs. Annars blir en knapp gjord. 

Visar kontakterna

Vi har avslutat den mest utmanande delen. Nu är allt som är kvar att visa dessa kontakter som en lista. De Kontakter behållare är det bästa stället för den logiken. 

Importreakt, Komponent från "reagera"; importera connect från 'react-redux'; / * Komponentimport utelämnas för korthet * / klass Kontakt utökar komponent konstruktör (rekvisita) super (rekvisita); this.returnContactList = this.returnContactList.bind (this);  returnContactList () returnera this.props.contactList;  render () returnera ( 


); funktionskartaStateToProps (state) return contactList: state.contacts.contactList exportera standardkoppling (mapStateToProps, null) (Kontakt);

Vi har gått igenom samma procedur som vi följde ovan för att ansluta komponenten Kontakter med Redux-butiken. De mapStateToProps funktionen kartlägger affärsobjektet till kontaktlista rekvisita. Vi använder sedan ansluta för att binda rekvisitionsvärdet till kontaktkomponenten. Det andra argumentet för anslutningen är null eftersom vi inte har några åtgärder som ska skickas. Det kompletterar integreringen av vår app med Redux-butiken. 

Vad Nästa?

I nästa inlägg tar vi en djupare titt på middleware och börjar skicka åtgärder som innebär att vi hämtar data från servern. Dela dina tankar i kommentarerna!