React Crash Course för nybörjare, del 3

Hittills i denna React-serie har vi skapat en arbetsprovapp som utgångspunkt för vår "Movie Mojo" -galleriapp, och vi har sett hur användandet av props gör det möjligt för oss att anpassa utseendet på komponenter genom att skicka in data i stället för hårt kodande det.

I del tre skapar vi vår första anpassade komponent och lägger sedan till tillstånd i vår app. Detta gör det möjligt för oss att enkelt hantera appdata utan att vara oroad över att manuellt uppdatera DOM. I stället ser vi hur man låter React hantera hela DOM-rendering från och med nu.

En uppsättning med fyra filmer kommer att visas i vårt galleri på sidan, och ytterligare fyra laddas och visas när Ladda mer…  knappen klickas.

Låt oss först tacka lägga till  komponent som visar information om en enskild film.

Lägga till en filmkomponent

De  komponenten visar information om en enskild film. Flera olika  Komponenterna kommer att visas tillsammans för att bilda ett filmgalleri av några bra filmer. Därför namnet på vår React app, "Movie Mojo"!

Innan vi lägger till  komponent, låt oss uppdatera CSS i App.js att utforma enskilda filmer i galleriet. Öppna App.css och ersätt stilar med:

.App text-align: center;  .App-logotyp animation: App-logo-spin oändlig 20s linjär; höjd: 80px;  .App-header bakgrundsfärg: steelblue; höjd: 70px; vaddering: 20px; färg vit;  .App-intro font-size: large;  / * ny css för filmkomponent * / * box-size: border-box;  .movies display: flex; flex-wrap: wrap;  .App-header h2 margin: 0;  .add-filmer text-align: center;  .add-movies-knappen font-size: 16px; vaddering: 8px; marginal: 0 10px 30px 10px;  .movie vaddering: 5px 25px 10px 25px; max bredd: 25%; 

Detta utformar galleriet för att visa filmer i en gridformation och förbättra avståndet runt andra visuella element.

Också i / Public / affischer /, Jag har lagt till 12 film posters för bekvämlighet som du kan använda i ditt eget projekt, om du följer med. Du kan ladda ner dem som en del av det färdiga projektet för del 4. Kopiera bara över posters mapp till din egen React app offentlig mapp.

Du kan också ladda ner dina egna filmposter från den ursprungliga webbplatsen. För den här handledningen använde jag cinematerial.com för alla filmposter. Det finns en liten avgift för att ladda ner affischer, men det finns förmodligen många andra källor till affischer om du vill försöka någon annanstans.

OK, tillbaka till vårt  komponent. Inuti / src / komponenter / mapp, skapa en ny Movie.js fil, öppna den i en redigerare och lägg till följande:

Importreakt, Komponent från "reagera"; klassfilmen utökar komponent render () return ( 

this.props.title

(this.props.year)

this.props.description

); exportera standardfilm;

Det här är ungefär som

 komponent förutom att vi refererar till flera rekvisita snarare än bara den. Låt oss använda vår  komponent för att visa några filmer.

I App.js lägg till fyra  komponenter inuti a

 wrapper så att vi enkelt kan tillämpa stilar till bara filmelementen. Här är den fulla App.js koda:

Importreakt, Komponent från "reagera"; importera "... /App.css"; importera rubrik från "./Header"; importera film från './Movie'; klass App utökar komponent render () return ( 

Dela några av våra favoritfilmer

); exportera standard App;

Observera hur vi explicit importerar  komponent, precis som vi gjorde för

, för att göra den tillgänglig i koden. Varje filmkomponent implementerar rekvisita för titel, år, beskrivning, och affisch.

Resultatet är fyra  komponenter till vårt galleri.

Det är väldigt tråkigt att lägga till filmer manuellt en i taget App.js. I praktiken kommer appdata sannolikt att komma från en databas och tillfälligt lagras i ett JSON-objekt innan de läggs till i statobjektet i din app.

Hantera React State

Vad är tillståndet i en React app? Du kan tänka på det som ett enda JavaScript-objekt som representerar all data i din app. Stat kan definieras på vilken komponent som helst, men om du vill dela tillstånd mellan komponenter är det bättre att definiera det på den översta komponenten. Stat kan sedan skickas ner till barnkomponenter och öppnas efter behov.

Även om staten är ett huvudobjekt, kan objektet innehålla flera delobjekt som är relaterade till olika delar av din app. I en kundvagns-app kan du till exempel ha ett statligt objekt för objekten i din beställning och ett annat objekt för övervakning av lager.

I vår "Movie Mojo" -app har vi bara ett delstatobjekt för att lagra filmerna i vårt galleri.

Kärnidén bakom att använda staten är att när data i din app ändras, uppdaterar React de relevanta delarna av DOM för dig. Allt du behöver göra är att hantera data, eller ange, i din app och React hanterar alla DOM-uppdateringar.

Lägger till filmer via stat

För enkelhetens skull kommer vi att avstå från databassteget och låtsas att våra filmdata har hämtats från en databas och lagrats i JSON-format.

För att visa att du lägger till objekt i ett initialt tillstånd, samt uppdatering av tillståndet när en händelse inträffar (t.ex. en knapptryckning) använder vi två JSON-objekt, var och en innehåller data om fyra filmer.

I src mapp, lägg till en ny movies.js fil, öppna den i en redigerare och lägg till följande kod för att definiera våra två JSON-objekt:

// några provfilmer const initialMovies = movie1: title: "Ferris Bueller's Day Off", år: "1986", beskrivning: "En högskolevis kille är fast besluten att ha en ledig dag från skolan, trots vad huvudmannen tycker av det. ", affisch:" ./posters/ferris.png ", movie2: title:" Bridget Jones Diary ", år:" 2001 ", beskrivning:" En brittisk kvinna är fast besluten att förbättra sig medan hon ser ut för kärlek i ett år där hon håller en personlig dagbok. ", affisch:" ./posters/bridget-jones.png ", movie3: title:" 50 Första Datum ", år:" 2004 ", beskrivning:" Henry Roth är en man rädd för engagemang tills han träffar den vackra Lucy. De slår av och Henry tror att han äntligen har hittat sin drömflicka. ", Affisch:" ./posters/50-first-dates.png " , film4: title: "Matilda", år: "1996", beskrivning: "Historia om en underbar liten tjej, som råkar vara ett geni och hennes underbara lärare vs. de värsta föräldrarna någonsin och den värsta skolans huvudman är tänkbara. ", affisch:" ./posters/matil da.png "; const additionalMovies = movie5: title: "Dirty Dancing", år: "1987", beskrivning: "Spendera sommaren på en Catskills resort med sin familj, blir Frances 'Baby" Houseman kär i lektens dansinstruktör, Johnny Castle . ", affisch:" ./posters/dirty-dancing.png ", movie6: title:" När Harry Met Sally ", år:" 1989 ", beskrivning:" Harry och Sally har känt varandra i flera år, och är mycket goda vänner, men de är rädda att sex skulle förstöra vänskapen. ", affisch:" ./posters/when-harry-met-sally.png ", movie7: title:" Elf ", år:" 2003 ", beskrivning: "Efter en oavsiktlig oro på elva samhället på grund av hans ojämn storlek, skickas en man som en elva på Nordpolen till USA för att söka sin sanna identitet.", poster: "./posters/elf. png ", film8: title:" Grease ", år:" 1978 ", beskrivning:" Bra tjej Sandy och greaser Danny blev kär i sommar. När de oväntat upptäcker att de nu är i samma gymnasium de kan återställa sig r romantik? ", affisch:" ./posters/grease.png "; exportera initialMovies; exportera additionalMovies;

Innan vi kan referera till JSON-objekten i vår  komponent, vi måste importera dem. Lägg till detta till toppen av App.js:

importera initialMovies från "... / movies"; importera additionalMovies från "... / movies";

Varje JSON-objekt är nu tillgängligt via variablerna initialMovies och additionalMovies. Hittills har vi dock ingen stat i samband med vår app. Låt oss fixa det nu.

Toppnivån i vår "Movie Mojo" app är , så låt oss lägga till vårt statliga objekt här. Vi behöver tillstånd att initialiseras tillsammans med komponentklassen, som vi kan göra via konstruktörfunktionen.

När du använder en konstruktörsfunktion i en React-klass måste du ringa super() först som Komponent objekt som vi utvidgar behöver initieras före någonting annat. Plus, den detta sökordet kommer inte att vara tillgängligt inom konstruktören förrän efter det super() har återvänt.

För att initiera vår stat objekt, lägg till det här inuti  komponent klass:

konstruktör () super (); this.state = filmer: ; 

Detta skapar ett tomt statligt objekt för vår React-app. Med hjälp av verktygen React developer kan vi se stat objekt initierat direkt på  komponent.

Vi vill dock initiera stat Objekt med vissa filmer så att de direkt visas på sidladdning. För att göra detta kan vi initiera bio Ange objekt med initialMovies istället för ett tomt objekt.

konstruktör () super (); this.state = movies: initialMovies; 

Detta ställer in startläget för vår app till de fyra filmer som finns lagrade i initialMovies JSON-objektet, men filmerna i galleriet visas fortfarande via den hårdkodade  komponenter vi lagt till tidigare.

Vi behöver skriva ut filmerna i film statobjekt istället, vilket vi kan göra genom att använda en slinga för att iterera över varje film.

Börja med att ta bort det hårdkodade  komponenter och ersätt dem med:

Object. Keys (this.state.movies). Map (key => )

Denna kod kräver viss förklaring. De film statobjekt innehåller enskilda filmer lagrade som objekt, men för att iterera över dem skulle det vara lättare att arbeta med en array istället.

Så vi använder Object.keys () att fånga alla nycklar för filmobjekten och lagra dem i en array. Detta är sedan iterated över att använda .Karta(), och a  komponent utmatas för varje film i bio statobjekt.

Det finns ett par ändringar från det föregående sättet vi lade till , fastän. För det första skickar vi in ​​all information för en enskild film via en singel meta stötta. Det här är faktiskt bekvämare än tidigare, där vi angav en separat stämning för varje filmattribut.

Observera också att vi anger en nyckel- prop också. Detta används internt av React för att hålla reda på komponenter som har lagts till av slingan. Det är inte faktiskt tillgängligt för komponenten, så du bör inte försöka komma åt den i din egen kod.

Utan en nyckel- prop, React kastar ett fel, så det är viktigt att inkludera det. Reakt behöver veta vilka nya filmer som har lagts till, uppdaterats eller tagits bort så att det kan hålla allt synkroniserat.

Vi behöver göra en sak innan våra komponenter kan visas. Öppna Movie.js, och för varje referens till en prop, prefix den med meta, som följer:

this.props.meta.title

(this.props.meta.year)

this.props.meta.description

Laddar fler filmer

Vi har sett hur du visar filmer som har lagts till för att vår app ska initieras, men om vi ville uppdatera vårt filmgalleri vid någon tidpunkt?

Det här är React som verkligen lyser. Allt vi behöver göra är att uppdatera filmerna i film state object, och React uppdaterar automatiskt alla delar av vår app som använder det här objektet. Så, om vi lägger till några filmer, kommer React att utlösa  komponenter göra() Metod för att uppdatera vårt filmgalleri.

Låt oss se hur vi kan implementera detta.

Börja med att lägga till en HTML-knapp inuti den stängande div-wrappen i App.js.

När knappen klickas, en klassmetod loadAdditionalMovies kallas. Lägg till den här metoden till  komponent klass:

loadAdditionalMovies () var currentMovies = ... this.state.movies; var newMovies = Object.assign (currentMovies, additionalMovies); this.setState (movies: newMovies); 

Uppdateringsstatus är relativt enkelt så länge du följer den rekommenderade metoden, som är att kopiera det aktuella statobjektet till ett nytt objekt och uppdatera den kopian med nya objekt. Då, för att ställa in den nya staten, vi ringer this.setState och skicka i vårt nya statsobjekt för att skriva över den föregående. Så snart staten är uppdaterad uppdaterar React bara de delar av DOM som har påverkats av ändringen till stat.

Den första raden i loadAdditionalMovies () använder a spridning operatör för att kopiera alla egenskaper hos this.state.movies föremål för det nya currentMovies objekt.

Därefter använder vi Object.assign att sammanfoga två objekt tillsammans, vilket resulterar i att listan över nya filmer läggs till i den aktuella listan.

Det är bara ett steg vi måste slutföra före loadAdditionalMovies () Metoden kommer att fungera. För att referera till en anpassad komponentmetod måste vi först binda den manuellt till komponentklassen.

Det här är en reaktion på React och är bara något du måste komma ihåg att göra. När som helst en metod är tillgänglig utan att vara bunden manuellt, kommer React att klaga och kasta ett sammanställningsfel.

Lägg till detta till klasskonstruktören i App.js:

this.loadAdditionalMovies = this.loadAdditionalMovies.bind (this);

Så länge du kommer ihåg att använda den här lösningen för varje anpassad metod som kräver användning av detta, du kommer inte att lösa några problem.

Nu försöker du klicka på Ladda mer…  Knapp. Du borde se ytterligare fyra filmer till galleriet.

Detta visar en viktig styrka för React. Det vill säga låta dig fokusera på data i din app och lämna all den vardagliga uppdateringen av DOM till React. För att lägga till filmer var allt vi behövde uppdatera data i vår film state object, och React tog hand om allt annat.

Vårt exempelapp är fortfarande ganska grundläggande, men föreställ dig en mycket mer komplex app med många komponenter och flera statliga objekt. Att försöka manuellt uppdatera DOM eftersom uppgifterna i dina appändringar skulle vara en stor (och felaktig) uppgift!

Slutsats

I den här handledningen gjorde vi verkligen framsteg med vår "Movie Mojo" -app. Vi använde React-status för att hantera listan över filmer i vår app. Inte bara lade vi till filmer till det ursprungliga tillståndsobjektet eftersom vår app initialiserades, men vi uppdaterade också listan med filmer i vårt galleri när Ladda mer…  Knappen klickades.

I del fyra och den sista handledningen i denna serie tittar vi på hur vi manuellt kan lägga till en film i vårt galleri via en anpassad blankett. Användare kommer att kunna fylla i formuläret och lägga till detaljer om en film, som läggs till i listan över filmer som visas i galleriet.