Bouw een React-app met een Laravel-back-end deel 2, Reageren

Wat je gaat creëren

Dit is het tweede en laatste deel van de serie over het bouwen van een React-applicatie met een back-end van Laravel. In het eerste deel van de serie hebben we een RESTful API gemaakt met behulp van Laravel voor een basisproductlijsttoepassing. In deze tutorial zullen we de voorkant ontwikkelen met behulp van React. 

We zullen ook alle beschikbare opties overwegen om de kloof tussen Laravel en React te overbruggen. U hoeft deel 1 van de serie niet te hebben gevolgd om deze zelfstudie te begrijpen. Als je hier bent om te zien hoe React en Laravel samen zijn, kun je in feite het eerste deel vermijden. Je moet naar GitHub gaan, de repo klonen en de korte samenvatting hieronder maken om aan de slag te gaan.

Een snelle samenvatting

In de vorige zelfstudie hebben we een Laravel-toepassing ontwikkeld die reageert op API-aanroepen. We hebben routes, een controller en een model gemaakt voor de eenvoudige productvermeldingsapplicatie. Omdat het de taak van de controller was om een ​​antwoord op de HTTP-verzoeken terug te sturen, werd de weergavesectie volledig overgeslagen. 

Daarna bespraken we technieken voor het afhandelen van uitzonderingen en validatie met Laravel. Aan het einde van de zelfstudie hadden we een back-end-API van Laravel. We kunnen deze API nu gebruiken om applicaties voor zowel het web als een breed scala aan mobiele apparaten te bouwen. 

In deze tutorial zullen we onze focus verleggen naar de voorkant. De eerste helft van de zelfstudie gaat over het opzetten van React in een Laravel-omgeving. Ik zal je ook Laravel Mix voorstellen (ondersteund door Laravel 5.4 en later), een API voor het compileren van assets. In de tweede helft van de zelfstudie beginnen we met het bouwen van een React-applicatie. 

Opzetten Reageren in Laravel

Laravel Mix werd geïntroduceerd in Laravel 5.4 en het is momenteel de ideale manier om React en Laravel aan te sluiten. Met Laravel 5.5 werd het hele proces veel eenvoudiger gemaakt. Ik heb beide methoden hieronder beschreven. 

Het React Preset Command gebruiken (Laravel 5.5)

Laravel 5.5 heeft een gloednieuwe functie waarmee je de code voor React-componenten kunt schaven met behulp van artisan's vooraf ingesteld reageren commando. In eerdere versies van Laravel was het opzetten van React in Laravel niet zo eenvoudig. Als u de nieuwste versie van Laravel gebruikt, voert u de onderstaande opdracht uit om een ​​React-voorinstelling toe te voegen aan uw project. 

php artisan preset reageren

Standaard wordt Laravel verzonden met de Vue-preset en de bovenstaande opdracht vervangt alle instanties van Vue door React. Interessant is dat als je geen preset nodig hebt, je ze allemaal kunt verwijderen met de php artisan preset geen commando. 

Als alles goed gaat, moet dit worden weergegeven in uw terminal.

Reageren steigers geïnstalleerd met succes. Voer "npm install && npm run dev" uit om uw nieuwe steigers samen te stellen. 

Op de achtergrond gebruikt Laravel Laravel Mix, een soepel omhulsel voor webpack. Webpack is, zoals je misschien al weet, een modulebundelaar. Het lost alle moduleafhankelijkheden op en genereert de noodzakelijke statische activa voor JavaScript en CSS. React vereist een modulebundelaar om te werken en webpack past perfect in die rol. Laravel Mix is ​​dus de laag bovenop webpack en maakt het eenvoudiger om webpack in Laravel te gebruiken.  

Een beter begrip van hoe Laravel Mix werkt, is belangrijk als u de configuratie van de webpack op een later tijdstip moet aanpassen. De opdracht React preset geeft ons geen informatie over hoe dingen op de achtergrond werken. Laten we dus de React-voorinstelling verwijderen en de stappen in plaats daarvan handmatig opnieuw uitvoeren. 

Handmatige methode (Laravel 5.4)

Als u Laravel 5.4 gebruikt of als u gewoon benieuwd bent naar hoe Laravel Mix is ​​geconfigureerd, volgt u de stappen die u moet volgen:

Installeren Reageer, reactie-dom en babel-preset reageren met behulp van npm. Het is misschien een goed idee om garen ook te laten installeren. Het is geen geheim dat Laravel en React garen boven npm verkiezen.

Ga naar webpack.mix.js, bevindt zich in de hoofdmap van uw Laravel-project. Dit is het configuratiebestand waarin u verklaart hoe uw activa moeten worden gecompileerd. Vervang de lijn mix.js ('resources / assets / js / app.js', 'public / js'); met mix.react ('resources / assets / js / app.js', 'public / js');. app.js is het toegangspunt voor onze JavaScript-bestanden en de gecompileerde bestanden zullen zich binnenin bevinden public / js. Rennen npm installeren in de terminal om alle afhankelijkheden te installeren.

Ga vervolgens naar resources / assets / js. Er is al een map met componenten en een paar andere JavaScript-bestanden. Reactieve componenten gaan naar de componentendirectory. Verwijder het bestaande Example.vue-bestand en maak een nieuw bestand aan voor een voorbeeld van een React-component.

resources / assets / js / component / main.js

import Reageren, Component uit 'reageren'; import ReactDOM van 'react-dom'; / * Een voorbeeld Reactie component * / class Hoofd breidt component render () return uit ( 

Alle producten

); standaard hoofd exporteren; / * De if-instructie is vereist om het onderdeel op pagina's met een div met een ID van "root" te renderen; * / if (document.getElementById ('root')) ReactDOM.render (
, document.getElementById ( 'root'));

Bijwerken app.js om alle Vue-gerelateerde code te verwijderen en in plaats daarvan het React-onderdeel te importeren. 

resources / assets / js / app.js

require ( './ bootstrap'); / * Importeer het hoofdonderdeel * / importeer Main vanuit './components/Main';

Nu moeten we de activa toegankelijk maken voor de weergave. De weergavebestanden bevinden zich in de resources / uitzicht directory. Laten we er een toevoegen

Eindelijk, voer uit npm run dev of garen lopen dev om de activa te compileren. Als u localhost: 8000 bezoekt, zou u moeten zien:

Reageer ingebed in de visie van Laravel.

De package.json heeft een wachtscript dat de items automatisch compileert wanneer er wijzigingen worden gedetecteerd. Als u deze modus wilt inschakelen, voert u uit npm run horloge

Gefeliciteerd, je hebt React succesvol geconfigureerd om met Laravel te werken. Laten we nu een aantal React-componenten voor de voorkant maken. 

De React-applicatie ontwikkelen

Als je nog niet bekend bent met Reageren, zul je de rest van de tutorial enigszins uitdagend vinden. Ik raad aan de React Crash Course for Beginners-serie te volgen om beter kennis te maken met de React-concepten. Laten we beginnen!

Een React-applicatie is opgebouwd rond componenten. Componenten zijn de belangrijkste structuur in React en we hebben een directory speciaal voor componenten.

Met onderdelen kun je de gebruikersinterface opsplitsen in onafhankelijke, herbruikbare stukken en afzonderlijk over elk onderdeel nadenken. Conceptueel zijn componenten als JavaScript-functies. Ze accepteren willekeurige ingangen ("rekwisieten" genoemd) en geven React-elementen terug die beschrijven wat er op het scherm zou moeten verschijnen.
- Officiële React-documenten

Voor de toepassing die we bouwen, beginnen we met een basiscomponent die alle producten weergeeft die door de server worden geretourneerd. Laten we het het hoofdonderdeel noemen. Het onderdeel moet in eerste instantie zorgen voor de volgende dingen:

  • Haal alle producten uit de API op (GET / api / producten).
  • Bewaar de productgegevens in de oorspronkelijke staat.
  • Toon de productgegevens.

Reageren is geen volwaardig kader en daarom heeft de bibliotheek zelf geen AJAX-functies. Ik zal gebruiken ophalen (), Dit is een standaard JavaScript-API om de gegevens van de server op te halen. Maar er zijn talloze alternatieven om AJAX-oproepen naar de server te maken. 

resources / assets / js / component / main.js

import Reageren, Component uit 'reageren'; import ReactDOM van 'react-dom'; / * Hoofdcomponent * / class Main breidt component constructor () super () uit; // Initialiseer de status in de constructor this.state = products: [], / * componentDidMount () is een levenscyclusmethode * die wordt aangeroepen nadat de component is gemaakt * / componentDidMount () / * API ophalen in actie * / fetch ('/ api / products') .then (response => return response.json ();) .then (products => // Fetched product is opgeslagen in de staat this.setState (producten ););  renderProducts () return this.state.products.map (product => return (/ * Bij gebruik van een lijst moet u een sleutel * -kenmerk opgeven dat uniek is voor elk lijstitem * / 
  • product.title
  • ); ) render () / * Sommige CSS-code is verwijderd voor beknoptheid * / return (
      this.renderProducts ()
    );

    Hier initialiseren we de staat van producten naar een lege array in de constructor. Zodra het onderdeel is aangekoppeld, gebruiken we ophalen () om de producten terug te halen /api/ producten en sla het op in de staat. De rendermethode wordt gebruikt om de gebruikersinterface van het onderdeel te beschrijven. Alle producten worden daar weergegeven als een lijst. 

    De pagina vermeldt alleen de producttitels, wat saai is. Bovendien hebben we daar nog geen interactieve elementen in. Laten we de producttitel klikbaar maken en klik op, meer details over het product worden weergegeven. 

    Productgegevens weergeven

    Dit is de lijst met dingen die we moeten behandelen:

    • Een staat om het product te volgen waarop is geklikt. Laten we het noemen currentProduct met een initiaal nul waarde.
    • Wanneer op een producttitel wordt geklikt, this.state.currentProduct is geüpdatet.
    • De productdetails van het betreffende product worden rechts weergegeven. Totdat een product is geselecteerd, wordt het bericht "Geen product geselecteerd" weergegeven.

    resources / assets / js / component / main.js

    import Reageren, Component uit 'reageren'; import ReactDOM van 'react-dom'; / * Hoofdcomponent * / class Main breidt component constructor () super () uit; / * currentProduct houdt bij welk product momenteel wordt * weergegeven * / this.state = producten: [], huidigProduct: null componentDidMount () // code weggelaten voor beknoptheid renderProducts () return this.state.products. kaart (product => return (//this.handleClick () methode wordt aangeroepen onClick. 
  • this.handleClick (product) -sleutel = product.id> product.title
  • ); ) handleClick (product) // handleClick wordt gebruikt om de staat this.setState (currentProduct: product) in te stellen; render () / * Sommige CSS-code is verwijderd voor beknoptheid * / return (
      this.renderProducts ()
    );

    Hier hebben we toegevoegd createProduct in de staat en initialiseerde het met de waarde nul. De lijn onClick = () => this.handleClick (product) roept de handleClick () methode wanneer op het lijstitem wordt geklikt. De handleClick () methode werkt de status van bij currentProduct

    Om de productgegevens weer te geven, kunnen we deze binnen het hoofdonderdeel weergeven of een nieuw onderdeel maken. Zoals eerder vermeld, is het splitsen van de gebruikersinterface in kleinere componenten de React-manier om dingen te doen. Dus we zullen een nieuw onderdeel maken en het Product noemen.

    Het onderdeel Product is genest in het hoofdonderdeel. Het hoofdonderdeel geeft zijn toestand door als rekwisieten. Het productonderdeel accepteert deze rekwisieten als invoer en geeft de relevante informatie weer.

    resources / assets / js / component / main.js

    render () return (/ * De extra divs zijn voor de CSS-stijlen * / 

    Alle producten

      this.renderProducts ()
    );

    resources / assets / js / component / Product.js

    import Reageren, Component uit 'reageren'; / * Syntaxis van stateless component of pure component * product is het vernietigen van objecten * / const Product = (product) => const divStyle = / * code weggelaten voor beknoptheid * / // als het props-product null is , retour Product bestaat niet als (! product) retourneren (
    Product bestaat niet
    ); // Anders, geeft u de productgegevens terug (

    Product.title

    Productomschrijving

    Status product.beschikbaarheid? 'Beschikbaar': 'Niet op voorraad'

    Prijs: product.price

    ) standaardproduct exporteren;

    De applicatie zou er nu ongeveer zo uit moeten zien:

    Een nieuw product toevoegen

    We hebben met succes de frontend geïmplementeerd die overeenkomt met het ophalen van alle producten en het weergeven ervan. Vervolgens hebben we een formulier nodig om een ​​nieuw product aan de productlijst toe te voegen. Het proces voor het toevoegen van een product kan een beetje ingewikkelder aanvoelen dan alleen het ophalen van de gegevens uit een API.

    Dit is wat ik denk dat nodig is om deze functie te ontwikkelen:

    • Een nieuwe stateful component die de gebruikersinterface voor een invoerformulier maakt. De status van de component bevat de formuliergegevens.
    • Bij indienen geeft de onderliggende component de status door aan de hoofdcomponent met behulp van een callback.
    • Het hoofdonderdeel heeft bijvoorbeeld een methode handleNewProduct (), die de logica verwerkt voor het starten van een POST-aanvraag. Na ontvangst van het antwoord, werkt het hoofdonderdeel zijn status bij (beide this.state.products en this.state.currentProduct

    Dat klinkt niet erg ingewikkeld, toch? Laten we het stap voor stap doen. Maak eerst een nieuw onderdeel. Ik ga het noemen AddProduct

    resources / assets / js / component / AddProduct.js

    klasse AddProduct breidt component constructor (rekwisieten) super (rekwisieten); / * Initialiseer de status. * / this.state = nieuwProduct: title: ", description:", price: 0, availability: 0 // Boilerplate-code voor bindmethoden met 'this' this.handleSubmit = this.handleSubmit.bind (this) ; this.handleInput = this.handleInput.bind (this);  / * Deze methode accepteert ingangen dynamisch en slaat deze op in de staat * / handleInput (key, e) / * Dupliceren en bijwerken van de staat * / var state = Object.assign (, this.state.newProduct); staat [key] = e.target.value; this.setState (newProduct: state);  / * Deze methode wordt aangeroepen wanneer de submit-knop wordt ingedrukt * / handleSubmit (e) // preventDefault voorkomt het opnieuw laden van de pagina e.preventDefault (); / * Een terugroep naar de onAdd-rekwisieten. De huidige * staat wordt doorgegeven als een param * / this.props.onAdd (this.state.newProduct);  render () const divStyle = / * Code weggelaten voor beknoptheid * / return ( 

    Voeg nieuw product toe

    / * wanneer knop Verzenden wordt ingedrukt, wordt het besturingselement doorgegeven aan * handleSubmit-methode * /
    / * Invoervelden voor prijs en beschikbaarheid zijn weggelaten voor de kortheid * /
    ) standaard export AddProduct;

    Het onderdeel maakt in feite een invoerformulier aan en alle invoerwaarden worden opgeslagen in de staat (this.state.newProduct). Vervolgens, op formulier indienen, handleSubmit () methode wordt aangeroepen. Maar AddProduct moet de informatie teruggeven aan de ouder, en we doen dit met behulp van een callback. 

    Het hoofdonderdeel, dat de ouder is, geeft een functie-verwijzing door als rekwisieten. De onderliggende component, AddProduct in ons geval roept dit rekwisieten op om de ouder op de hoogte te stellen van de verandering van de staat. Dus de lijn this.props.onAdd (this.state.newProduct); is een voorbeeld van een callback die de bovenliggende component van het nieuwe product waarschuwt. 

    Nu, binnen het hoofdonderdeel, zullen we verklaren als volgt:

     

    De onAdd gebeurtenishandler is aan de componenten gekoppeld handleAddProduct () methode. Deze methode host de code voor het maken van een POST-aanvraag naar de server. Als het antwoord aangeeft dat het product met succes is gemaakt, is de staat van producten en currentProducts is geüpdatet. 

     handleAddProduct (product) product.price = Number (product.price); / * Fetch API voor postverzoek * / fetch ('api / products /', method: 'post', / * headers zijn belangrijk * / headers: 'Accept': 'application / json', 'Content-Type' : 'application / json', body: JSON.stringify (product)) .then (response => return response.json ();) .then (data => // update de status van producten en currentProduct this.setState ((prevState) => (products: prevState.products.concat (data), currentProduct: data))) 

    Vergeet niet om het te binden handleProduct methode om de klas te gebruiken this.handleAddProduct = this.handleAddProduct.bind (this); in de constructor. En hier is de definitieve versie van de applicatie:

    Wat nu?

    De applicatie is onvolledig zonder de functies voor verwijderen en bijwerken. Maar als je de tutorial tot nu toe nauwlettend hebt gevolgd, zou je in staat moeten zijn om de leegte zonder veel moeite in te vullen. Om u op weg te helpen, heb ik u de gebeurtenishandlerlogica gegeven voor zowel het verwijderings- als het updatescenario.

    Logica voor het verwijderen van een product

     handleDelete () const currentProduct = this.state.currentProduct; fetch ('api / products /' + this.state.current Product.id, method: 'delete') .then (response => / * Dupliceer de array en filter het item uit dat moet worden verwijderd * / var array = this.state.products.filter (functie (item) retourartikel! == huidigProduct); this.setState (products: array, currentProduct: null);); 

    Logica voor het bijwerken van een bestaand product

    handleUpdate (product) const currentProduct = this.state.currentProduct; fetch ('api / products /' + currentProduct.id, methode: 'put', headers: 'Accept': 'application / json', 'Content-Type': 'application / json', hoofdtekst: JSON. stringify (product)) .then (response => return response.json ();) .then (data => / * De status bijwerken * / var array = this.state.products.filter (function (item ) return item! == currentProduct) this.setState ((prevState) => (producten: array.concat (product), currentProduct: product))) 

    Wat je moet doen, is erin duiken, handen vies maken en de applicatie afsluiten met de bovenstaande logica. Ik zal u een hint geven: De verwijderknop zou idealiter in het Product-onderdeel moeten gaan, terwijl de update-functie een eigen component zou moeten hebben. Ik moedig je aan om deze uitdaging aan te gaan en de ontbrekende componenten te voltooien.

    Samenvatting

    We zijn ver gekomen van waar we zijn begonnen. Eerst hebben we een REST API gemaakt met behulp van het Laravel-framework. Daarna hebben we onze opties voor het mengen van Laravel en React besproken. Ten slotte hebben we een frontend voor de API gebouwd met behulp van React. 

    Hoewel we ons voornamelijk hebben gericht op het maken van een toepassing met één pagina met React, kunt u widgets of componenten maken die zijn gekoppeld aan specifieke elementen in uw weergaven. Reageren is erg flexibel omdat het een bibliotheek is en een goede bibliotheek.

    In het afgelopen jaar is React in populariteit gegroeid. We hebben zelfs een aantal items op de markt die beschikbaar zijn voor aankoop, beoordeling, implementatie enzovoort. Als u op zoek bent naar extra bronnen rond React, aarzel dan niet om ze te bekijken.

    Heb je eerder geprobeerd te experimenteren met Laravel en React? hoe denk jij erover? Deel ze met ons in de comments.