Bygg en React App med en Laravel Back End Del 2, React

Hva du skal skape

Dette er den andre og siste delen av serien om å bygge et React-program med en Laravel-bakside. I den første delen av serien opprettet vi et RESTful API ved hjelp av Laravel for et grunnleggende produktoppføringsprogram. I denne opplæringen vil vi utvikle frontenden ved å bruke React. 

Vi vil også vurdere alle tilgjengelige alternativer for å bygge bro over gapet mellom Laravel og React. Du trenger ikke å ha fulgt en del av serien for å forstå denne opplæringen. Hvis du er her for å se hvordan React og Laravel går sammen, kan du faktisk unngå den første delen. Du bør gå over til GitHub, klone repoen, og ta den hurtige omgangen nedenfor for å komme i gang.

En rask oppskrift

I den forrige veiledningen utviklet vi et Laravel-program som svarer på API-anrop. Vi opprettet ruter, en kontroller og en modell for det enkle produktoppføringsprogrammet. Siden det var regulatorens jobb å returnere et svar på HTTP-forespørslene, ble visningsdelen helt hoppet over. 

Da diskuterte vi teknikker for unntakshåndtering og validering ved hjelp av Laravel. Ved slutten av opplæringen hadde vi en Laravel back-end API. Vi kan nå bruke denne API for å bygge programmer for både Internett og et bredt utvalg av mobile enheter. 

I denne opplæringen vil vi skifte fokus mot frontenden. Første halvdel av opplæringen handler om å sette opp React i et Laravel-miljø. Jeg vil også introdusere deg til Laravel Mix (støttet av Laravel 5.4 og senere), som er en API for å samle eiendeler. I andre halvdel av opplæringen begynner vi å bygge en React-applikasjon fra bunnen av. 

Sette opp React i Laravel

Laravel Mix ble introdusert i Laravel 5.4, og det er for tiden den ideelle måten å koble opp React og Laravel. Med Laravel 5.5 ble hele prosessen gjort mye enklere. Jeg har beskrevet begge metodene nedenfor. 

Bruke React Preset Command (Laravel 5.5)

Laravel 5.5 har en helt ny funksjon som lar deg sette opp koden for React-komponenter ved hjelp av håndverkeren forhåndsinnstilte reaksjoner kommando. I tidligere versjoner av Laravel var det ikke så lett å sette opp React inni Laravel. Hvis du kjører den nyeste versjonen av Laravel, kjør du deretter kommandoen nedenfor for å legge til en React forhåndsinnstilt til prosjektet ditt. 

php artisan forhåndsinnstilte reaksjon

Laravel leveres som standard med Vue forhåndsinnstilt, og kommandoen ovenfor erstatter alle forekomster av Vue with React. Interessant, hvis du ikke trenger en forhåndsinnstilt, kan du fjerne dem helt ved å bruke php artisan forhåndsinnstilt ingen kommando. 

Hvis alt går bra, bør dette dukke opp i din terminal.

Gjør stillasett installert vellykket. Vennligst kjør "npm installere && npm run dev" for å kompilere dine friske stillas. 

I bakgrunnen bruker Laravel Laravel Mix, som er en glatt innpakning for webpack. Webpack, som du kanskje allerede vet, er en modulpakker. Det løser alle modulavhengighetene og genererer de nødvendige statiske aktiva for JavaScript og CSS. Reakt krever en modulpakker til å fungere, og webpack passer perfekt til den rollen. Så Laravel Mix er laget som sitter på toppen av webpack og gjør det enklere å bruke webpack i Laravel.  

En bedre forståelse av hvordan Laravel Mix fungerer, er viktig hvis du trenger å tilpasse webpack-konfigurasjonen på et senere tidspunkt. Kommandoen React preset gir oss ingen informasjon om hvordan ting fungerer i bakgrunnen. Så la oss fjerne React forhåndsinnstilt og gå tilbake trinnene manuelt i stedet. 

Manuell metode (Laravel 5.4)

Hvis du kjører Laravel 5.4, eller hvis du bare er nysgjerrig på hvordan Laravel Mix er konfigurert, er disse trinnene du må følge:

Installere reagere, reagere-dom og babel-forhåndsreagere bruker npm. Det kan være lurt å ha garn installert også. Det er ingen hemmelighet at Laravel og React foretrekker garn over npm.

Gå over til webpack.mix.js, plassert i rotkatalogen av Laravel-prosjektet ditt. Dette er konfigurasjonsfilen der du erklærer hvordan dine eiendeler skal kompileres. Bytt ut linjen mix.js ('ressurser / assets / js / app.js', 'public / js'); med mix.react ('ressurser / assets / js / app.js', 'public / js');. app.js er inngangspunktet for våre JavaScript-filer, og de kompilerte filene vil bli plassert inne offentlige / js. Løpe npm installasjon i terminalen for å installere alle avhengighetene.

Deretter går til ressurser / eiendeler / js. Det er allerede en komponentmappe og et par andre JavaScript-filer. Reaktorkomponenter vil gå inn i komponentkatalogen. Fjern den eksisterende Example.vue-filen og opprett en ny fil for en prøve React-komponent.

ressurser / eiendeler / js / komponent / Main.js

Import React, Component fra 'reagere'; importere ReactDOM fra 'react-dom'; / * Et eksempel React component * / class Hoved utvider komponent render () return ( 

Alle produkter

); eksport standard Main; / * Hvis setningen er nødvendig for å Render komponenten på sider som har en div med en ID for "root"; * / if (document.getElementById ('root')) ReactDOM.render (
, document.getElementById ( 'root'));

Oppdater app.js for å fjerne all Vue-relatert kode og importere React-komponenten i stedet. 

ressurser / eiendeler / JS / app.js

kreve ( './ bootstrap'); / * Importer hovedkomponenten * / Import Main fra './components/Main';

Nå må vi bare gjøre eiendelene tilgjengelige for visningen. Visningsfilene er plassert inne i ressurser / utsikt katalogen. La oss legge til en

Endelig, utfør npm kjøre dev eller garn kjøre dev å kompilere eiendelene. Hvis du besøker localhost: 8000, bør du se:

Reagere innebygd i Laravel sikt.

De package.json har et klokkeskript som automatisk kompilerer eiendelene når eventuelle endringer oppdages. For å aktivere denne modusen, kjør npm kjøre klokke

Gratulerer, du har vellykket konfigurert React for å jobbe med Laravel. La oss nå lage noen React-komponenter for frontenden. 

Utvikling av React Application

Hvis du er ny til å reagere, finner du resten av opplæringen litt utfordrende. Jeg anbefaler å ta React Crash Course for Beginners-serien for å bli kjent med React-konseptene bedre. La oss komme i gang!

En React-applikasjon er bygd rundt komponenter. Komponenter er den viktigste strukturen i React, og vi har en katalog dedikert til komponenter.

Komponenter lar deg dele brukergrensesnittet i uavhengige, gjenbrukbare deler, og tenk på hvert stykke i isolasjon. Konseptuelt, komponenter er som JavaScript-funksjoner. De aksepterer vilkårlig inngang (kalt "rekvisitter") og returnerer React-elementer som beskriver hva som skal vises på skjermen.
- Offisielle reaksjonsdokumenter

For programmet som vi bygger, starter vi med en grunnleggende komponent som viser alle produktene som returneres av serveren. La oss nevne hovedkomponenten. Komponenten skal i første omgang ta vare på følgende ting:

  • Hent alle produktene fra API (GET / api / produkter).
  • Lag produktdataene i sin tilstand.
  • Vis produktdataene.

React er ikke et fullverdig rammeverk, og derfor har biblioteket ingen AJAX-funksjoner på egen hånd. Jeg skal bruke hente (), som er en standard JavaScript API for å hente data fra serveren. Men det er mange alternativer for å gjøre AJAX-samtaler til serveren. 

ressurser / eiendeler / js / komponent / Main.js

Import React, Component fra 'reagere'; importere ReactDOM fra 'react-dom'; / * Hovedkomponent * / klasse Hoved utvider komponent constructor () super (); // Initialiser staten i konstruktøren this.state = products: [], / * componentDidMount () er en livscyklusmetode * som blir kalt etter at komponenten er gjengitt * / componentDidMount () / * hent API i handling * / hente ('/ api / products') .then (response => return response.json ();) .then (products => // Fetched produkt er lagret i staten this.setState (products ););  renderProducts () return this.state.products.map (product => return (/ * Når du bruker listen må du angi en nøkkel * attributt som er unikt for hvert listepost * / 
  • product.title
  • ); ) render () / * Noen css-kode er fjernet for korthet * / retur (
      this.renderProducts ()
    );

    Her initialiserer vi tilstanden til Produkter til en tom matrise i konstruktøren. Når komponenten monterer, bruker vi hente () å hente produktene fra /api/Produkter og lagre den i staten. Gjenvinningsmetoden brukes til å beskrive komponentens brukergrensesnitt. Alle produktene blir gjengitt som en liste der. 

    Siden viser bare produkttitlene, som er kjedelig. Videre har vi ikke noen interaktive elementer der inne ennå. La oss få produktet tittel klikkbare, og på klikk, vil flere detaljer om produktet bli gjengitt. 

    Viser produktdata

    Her er listen over ting som vi trenger å dekke:

    • En stat for å spore produktet som ble klikket. La oss kalle det currentProduct med en innledende null verdi.
    • Når en produkttittel klikkes, this.state.currentProduct er oppdatert.
    • Produktets detaljer for det aktuelle produktet vises til høyre. Inntil et produkt er valgt, vises meldingen "Ingen produkt valgt".

    ressurser / eiendeler / js / komponent / Main.js

    Import React, Component fra 'reagere'; importere ReactDOM fra 'react-dom'; / * Hovedkomponent * / klasse Hoved utvider komponent constructor () super (); / * currentProduct holder styr på produktet som for tiden * vises * / this.state = produkter: [], nåværendeProdukt: null componentDidMount () // kode utelatt for korthet renderProducts () return this.state.products. Kart (product => return (//this.handleClick () -metoden er påkalt onClick. 
  • this.handleClick (produkt) nøkkel = product.id> product.title
  • ); ) handleClick (produkt) // handleClick brukes til å angi tilstanden this.setState (currentProduct: product); gjengivelse () / * Noen css-kode er fjernet for korthet * / retur (
      this.renderProducts ()
    );

    Her har vi lagt til createProduct inn i staten og initialisert den med verdien null. Køen onClick = () => this.handleClick (produkt) påberoper seg handleClick () metode når listeposten er klikket. De handleClick () Metoden oppdaterer tilstanden til currentProduct

    Nå for å vise produktdataene, kan vi enten gjøre det i hovedkomponenten eller opprette en ny komponent. Som tidligere nevnt, er splittelsen av brukergrensesnittet i mindre komponenter React-måten å gjøre ting på. Så vi vil opprette en ny komponent og nevne den Produkt.

    Produktkomponenten er nestet inne i hovedkomponenten. Hovedkomponenten passerer sin tilstand som rekvisitter. Produktkomponenten aksepterer disse rekvisita som input og gir relevant informasjon.

    ressurser / eiendeler / js / komponent / Main.js

    render () return (/ * De ekstra divene er for css stilene * / 

    Alle produkter

      this.renderProducts ()
    );

    ressurser / eiendeler / js / komponent / Product.js

    Import React, Component fra 'reagere'; / * Statløs komponent eller ren komponent * produkt syntaks er objektet ødelegger * / const Produkt = (produkt) => const divStyle = / * kode utelatt for korthet * / // hvis rekvisita produktet er null , retur Produkt eksisterer ikke hvis (! produkt) retur (
    Produkt eksisterer ikke
    ); // Ellers, vis produktdataavkastningen (

    Product.title

    produktbeskrivelse

    Status product.availability? 'Tilgjengelig': 'Tomt på lager'

    Pris: product.price

    ) eksporter standardprodukt;

    Søknaden bør se slik ut som dette nå:

    Legge til et nytt produkt

    Vi har vellykket implementert frontenden som svarer til å hente alle produktene og vise dem. Deretter trenger vi et skjema for å legge til et nytt produkt i produktlisten. Prosessen for å legge til et produkt kan føles litt mer komplisert enn bare å hente dataene fra en API.

    Her er det jeg tror er nødvendig for å utvikle denne funksjonen:

    • En ny stateful komponent som gjør brukergrensesnittet til en inngangsform. Komponentens tilstand inneholder formdataene.
    • Ved innsending passerer barnkomponenten staten til hovedkomponenten ved hjelp av tilbakeringing.
    • Hovedkomponenten har en metode, sier handleNewProduct (), som håndterer logikken for å starte en POST-forespørsel. Ved mottak av svar oppdaterer hovedkomponenten sin tilstand (begge deler) this.state.products og this.state.currentProduct

    Det høres ikke veldig komplisert ut, gjør det? La oss gjøre det trinnvis. Først oppretter du en ny komponent. Jeg skal kalle det AddProduct

    ressurser / eiendeler / JS / komponent / AddProduct.js

    klasse AddProduct utvider komponent constructor (rekvisitter) super (rekvisitter); / * Initialiser staten. * / this.state = newProduct: title: ", beskrivelse:", pris: 0, tilgjengelighet: 0 // Boilerplate kode for bindingsmetoder med 'this' this.handleSubmit = this.handleSubmit.bind ; this.handleInput = this.handleInput.bind (dette);  / * Denne metoden aksepterer dynamisk innganger og lagrer den i staten * / handleInput (nøkkel, e) / * Dupliserer og oppdaterer tilstanden * / var state = Object.assign (, this.state.newProduct); stat [nøkkel] = e.target.value; this.setState (newProduct: state);  / * Denne metoden er påkalt når innsendingsknappen er trykket * / handleSubmit (e) // preventDefault forhindrer sideopplasting e.preventDefault (); / * En ring tilbake til onAdd rekvisitter. Den nåværende * tilstanden er bestått som en param * / this.props.onAdd (this.state.newProduct);  render () const divStyle = / * Kode utelatt for korthet * / retur ( 

    Legg til nytt produkt

    / * Når Send-knappen er trykket, blir kontrollen overført til * håndtereSend inn metode * /
    / * Inngang felt for pris og tilgjengelighet utelatt for korthet * /
    ) eksporter standard AddProduct;

    Komponenten gjør i utgangspunktet et inntastingsskjema, og alle inngangsverdiene lagres i staten (this.state.newProduct). Deretter, på skjema innsending, handleSubmit () Metoden blir påkalt. Men AddProduct trenger å formidle informasjonen tilbake til foreldrene, og vi gjør dette ved hjelp av tilbakeringing. 

    Hovedkomponenten, som er forelder, sender en funksjonsreferanse som rekvisitter. Barnekomponenten, AddProduct i vårt tilfelle påberoper denne rekvisitter å varsle forelderen til statsendringen. Så linjen this.props.onAdd (this.state.newProduct); er et eksempel på en tilbakeringing som varsler om foreldrekomponenten i det nye produktet. 

    Nå, i hovedkomponenten, skal vi erklære som følger:

     

    De onAdd Hendelsehandler er koblet til komponentens handleAddProduct () metode. Denne metoden er vert for koden for å lage en POST-forespørsel til serveren. Hvis svaret indikerer at produktet har blitt opprettet, er tilstanden til Produkter og currentProducts er oppdatert. 

     handleAddProdukt (produkt) product.price = Number (product.price); / * Hent API for postforespørsel * / hente ('api / products /', metode: 'innlegg', / * overskrifter er viktige * / overskrifter: 'Accept': 'application / json', 'Content-Type' : 'application / json', body: JSON.stringify (produkt)) .then (response => return response.json ();) .then (data => // oppdater status for produkter og nåværendeProdukt this.setState ((prevState) => (produkter: prevState.products.concat (data), nåværendeProdukt: data))) 

    Ikke glem å binde handleProduct metode til klassen ved hjelp av this.handleAddProduct = this.handleAddProduct.bind (dette); i konstruktøren. Og her er den endelige versjonen av søknaden:

    Hva nå?

    Programmet er ufullstendig uten slettings- og oppdateringsfunksjonene. Men hvis du har fulgt opplæringen tett til nå, bør du kunne fylle ut tomrommet uten mye trøbbel. For å komme i gang, har jeg gitt deg hendelseshandlerlogikken for både slett og oppdateringsscenariet.

    Logikk for å slette et produkt

     handleDelete () const currentProduct = this.state.currentProduct; hente ('api / products /' + this.state.currentProduct.id, metode: 'delete') .then (response => / * Dupliser arrayet og filtrer ut elementet som skal slettes * / var array = this.state.products.filter (funksjon (element) returpunkt! == nåværendeProdukt); this.setState (produkter: array, nåværendeProdukt: null);); 

    Logikk for å oppdatere et eksisterende produkt

    handleUpdate (produkt) const currentProduct = this.state.currentProduct; hente ('api / products /' + currentProduct.id, metode: 'put', overskrifter: 'Accept': 'application / json', 'Content-Type': 'application / json', body: JSON. stringify (product)) .then (response => return response.json ();) .then (data => / * Oppdaterer tilstanden * / var array = this.state.products.filter (funksjon ) return item! == currentProduct) this.setState ((prevState) => (produkter: array.concat (produkt), nåværendeProdukt: produkt))) 

    Det du trenger å gjøre er å dykke inn, få hendene skitne, og avslutt søknaden ved hjelp av logikken ovenfor. Jeg vil gi deg et hint: Slett-knappen skal ideelt sett gå inn i produktkomponenten, mens oppdateringsfunksjonen skal ha en egen komponent. Jeg oppfordrer deg til å ta opp denne utfordringen og fullføre de manglende komponentene.

    Sammendrag

    Vi har kommet langt fra hvor vi startet. Først opprettet vi en REST API ved hjelp av Laravel-rammeverket. Da diskuterte vi alternativene våre for å blande Laravel og React. Til slutt bygde vi en frontend til API-en ved hjelp av React. 

    Selv om vi primært fokuserte på å lage et enkeltsidet program ved hjelp av React, kan du opprette widgets eller komponenter som er montert på bestemte elementer i visningene dine. React er veldig fleksibel fordi det er et bibliotek, og en god en.

    I løpet av de siste par årene har React vokst i popularitet. Faktisk har vi en rekke elementer i markedet som er tilgjengelige for kjøp, gjennomgang, implementering og så videre. Hvis du leter etter flere ressurser rundt React, ikke nøl med å sjekke dem ut.

    Har du prøvd å eksperimentere med Laravel og React før? Hva er dine tanker? Del dem med oss ​​i kommentarene.