Costruisci un'applicazione React con un back end Laravel parte 2, reagisci

Cosa starai creando

Questa è la seconda e ultima parte della serie sulla costruzione di un'applicazione React con un backend Laravel. Nella prima parte della serie, abbiamo creato un'API RESTful utilizzando Laravel per un'applicazione di elenco di prodotti di base. In questo tutorial, svilupperemo il front end usando React. 

Considereremo anche tutte le opzioni disponibili per colmare il divario tra Laravel e React. Non è necessario aver seguito la prima parte della serie per comprendere questo tutorial. Se sei qui per vedere come React e Laravel vanno insieme, puoi, in effetti, evitare la prima parte. Dovresti andare su GitHub, clonare il repository e prendere il riepilogo rapido qui sotto per iniziare.

Una rapida riassunzione

Nel precedente tutorial, abbiamo sviluppato un'applicazione Laravel che risponde alle chiamate API. Abbiamo creato percorsi, un controller e un modello per la semplice applicazione di elenco dei prodotti. Poiché era compito del controllore restituire una risposta alle richieste HTTP, la sezione di visualizzazione è stata interamente ignorata. 

Quindi abbiamo discusso le tecniche per la gestione delle eccezioni e la convalida utilizzando Laravel. Alla fine del tutorial, disponevamo di un'API back-end Laravel. Ora possiamo utilizzare questa API per creare applicazioni sia per il Web che per una vasta gamma di dispositivi mobili. 

In questo tutorial, sposteremo la nostra attenzione verso il front-end. La prima metà del tutorial riguarda la configurazione di React in un ambiente Laravel. Ti presenterò anche Laravel Mix (supportato da Laravel 5.4 e versioni successive), che è un'API per la compilazione delle risorse. Nella seconda parte del tutorial, inizieremo a creare un'applicazione React da zero. 

Configurare Reagire in Laravel

Laravel Mix è stato introdotto in Laravel 5.4 ed è attualmente il modo ideale per collegare React e Laravel. Con Laravel 5.5, l'intero processo è stato reso molto più semplice. Ho descritto entrambi i metodi di seguito. 

Utilizzo del comando React Preset (Laravel 5.5)

Laravel 5.5 ha una nuovissima funzionalità che ti consente di impalcettare il codice per i componenti React usando artigiano preset reagire comando. Nelle versioni precedenti di Laravel, impostare React in Laravel non era così facile. Se stai utilizzando l'ultima versione di Laravel, esegui il comando seguente per aggiungere un preset React al tuo progetto. 

php artisan preset reagire

Laravel di default viene fornito con il preset Vue, e il comando precedente sostituisce tutte le istanze di Vue con React. È interessante notare che, se non hai bisogno di un preset, puoi rimuoverli completamente usando il php artisan preset none comando. 

Se tutto va bene, questo dovrebbe apparire nel tuo terminale.

React scaffolding installato con successo. Esegui "npm install && npm run dev" per compilare il tuo nuovo ponteggio. 

In background, Laravel usa Laravel Mix, che è un wrapper liscio per il webpack. Il Webpack, come forse già saprai, è un modulo bundler. Risolve tutte le dipendenze del modulo e genera le risorse statiche necessarie per JavaScript e CSS. React richiede un bundler di moduli per funzionare e il webpack si adatta perfettamente a tale ruolo. Quindi Laravel Mix è il livello che si trova sulla parte superiore del webpack e rende più facile l'uso del webpack in Laravel.  

Una migliore comprensione di come funziona Laravel Mix è importante se è necessario personalizzare la configurazione del pacchetto Web in un secondo momento. Il comando di preset React non ci fornisce informazioni su come funzionano le cose in background. Quindi rimuoviamo il preset React e torniamo indietro manualmente. 

Metodo manuale (Laravel 5.4)

Se stai usando Laravel 5.4, o se sei solo curioso di vedere come è configurato Laravel Mix, ecco i passaggi che devi seguire:

Installare reagire, reagire-dom e babel-preset-reagire usando npm. Potrebbe essere una buona idea avere anche un filo installato. Non è un segreto che Laravel e React preferiscano il filato al minuto.

Dirigetevi verso webpack.mix.js, situato all'interno della directory principale del tuo progetto Laravel. Questo è il file di configurazione in cui dichiari come devono essere compilati i tuoi beni. Sostituisci la linea mix.js ('resources / assets / js / app.js', 'public / js'); con mix.react ('resources / assets / js / app.js', 'public / js');. app.js è il punto di ingresso per i nostri file JavaScript e i file compilati si troveranno all'interno / js pubblici. Correre installazione di npm nel terminale per installare tutte le dipendenze.

Avanti, vai a risorse / attività / js. C'è già una cartella dei componenti e un paio di altri file JavaScript. I componenti di React entreranno nella directory dei componenti. Rimuovere il file Example.vue esistente e creare un nuovo file per un componente React di esempio.

risorse / beni / js / component / main.js

import React, Component da 'react'; importare ReactDOM da 'react-dom'; / * Un esempio Componente React * / classe Main estende Component render () return ( 

Tutti i prodotti

); export default Main; / * L'istruzione if è richiesta in modo da rendere il componente su pagine che hanno un div con un ID di "root"; * / if (document.getElementById ('root')) ReactDOM.render (
, document.getElementById ( 'radice'));

Aggiornare app.js rimuovere tutto il codice relativo a Vue e importare invece il componente React. 

risorse / attività / js / app.js

require ( './ bootstrap'); / * Importare il componente principale * / import Main da './components/Main';

Ora, abbiamo solo bisogno di rendere le risorse accessibili alla vista. I file di visualizzazione si trovano all'interno di Resources / views directory. Aggiungiamo a

Finalmente, esegui npm run dev o filato dev compilare le risorse. Se visiti localhost: 8000, dovresti vedere:

Reagire incorporato nella vista di Laravel.

Il package.json ha uno script di sorveglianza che auto-compila le risorse quando vengono rilevate delle modifiche. Per abilitare questa modalità, corri npm esegui l'orologio

Congratulazioni, hai configurato correttamente React per funzionare con Laravel. Ora creiamo alcuni componenti React per il front-end. 

Sviluppo dell'applicazione React

Se sei nuovo su React, troverai il resto del tutorial piuttosto impegnativo. Raccomando di prendere la serie React Crash Course per principianti per familiarizzare meglio con i concetti di React. Iniziamo!

Un'applicazione React è costruita attorno ai componenti. I componenti sono la struttura più importante in React e abbiamo una directory dedicata ai componenti.

I componenti ti permettono di dividere l'interfaccia utente in pezzi indipendenti e riutilizzabili e di pensare a ciascun pezzo separatamente. Concettualmente, i componenti sono come le funzioni JavaScript. Accettano input arbitrari (chiamati "oggetti di scena") e restituiscono elementi React che descrivono cosa dovrebbe apparire sullo schermo.
- Documento ufficiale di Reazione

Per l'applicazione che stiamo creando, inizieremo con un componente di base che visualizza tutti i prodotti restituiti dal server. Diamo il nome al componente principale. Il componente dovrebbe occuparsi inizialmente delle seguenti cose:

  • Scarica tutti i prodotti dall'API (GET / api / products).
  • Memorizza i dati del prodotto nel suo stato.
  • Visualizza i dati del prodotto.

React non è un framework completo, e quindi la libreria non ha caratteristiche AJAX a se stante. Userò fetch (), che è un'API JavaScript standard per il recupero dei dati dal server. Ma ci sono un sacco di alternative per effettuare chiamate AJAX al server. 

risorse / beni / js / component / main.js

import React, Component da 'react'; importare ReactDOM da 'react-dom'; / * Componente principale * / classe Main estende Component constructor () super (); // Inizializza lo stato nel costruttore this.state = prodotti: [], / * componentDidMount () è un metodo del ciclo di vita * che viene chiamato dopo il rendering del componente * / componentDidMount () / * fetch API in azione * / fetch ('/ api / products') .then (response => return response.json ();) .then (products => // Il prodotto recuperato è archiviato nello stato this.setState (prodotti ););  renderProducts () return this.state.products.map (product => return (/ * Quando si utilizza l'elenco è necessario specificare un attributo chiave * che è univoco per ciascun elemento dell'elenco * / 
  • product.title
  • ); ) render () / * Alcuni codici CSS sono stati rimossi per brevità * / return (
      this.renderProducts ()
    );

    Qui stiamo inizializzando lo stato di prodotti a un array vuoto nel costruttore. Una volta montato il componente, usiamo fetch () per recuperare i prodotti da /api/prodotti e conservarlo nello stato. Il metodo di rendering viene utilizzato per descrivere l'interfaccia utente del componente. Tutti i prodotti vengono visualizzati come elenco. 

    La pagina elenca solo i titoli dei prodotti, che è noioso. Inoltre, non abbiamo ancora elementi interattivi. Rendiamo il titolo del prodotto selezionabile e, al clic, verranno resi più dettagli sul prodotto. 

    Visualizzazione dei dati del prodotto

    Ecco l'elenco delle cose che dobbiamo coprire:

    • Uno stato per tracciare il prodotto su cui è stato fatto clic. Chiamiamolo currentProduct con una iniziale nullo valore.
    • Quando viene cliccato il titolo di un prodotto, this.state.currentProduct è aggiornato.
    • I dettagli del prodotto del prodotto in questione sono visualizzati sulla destra. Fino a quando non viene selezionato un prodotto, visualizza il messaggio "Nessun prodotto selezionato".

    risorse / beni / js / component / main.js

    import React, Component da 'react'; importare ReactDOM da 'react-dom'; / * Componente principale * / classe Main estende Component constructor () super (); / * currentProduct tiene traccia del prodotto attualmente * visualizzato * / this.state = prodotti: [], currentProduct: null componentDidMount () // codice omesso per brevità renderProducts () return this.state.products. map (prodotto => return (//this.handleClick () metodo è invocato onClick. 
  • this.handleClick (prodotto) chiave = product.id> product.title
  • ); ) handleClick (prodotto) // handleClick viene utilizzato per impostare lo stato this.setState (currentProduct: product); render () / * Alcuni codici CSS sono stati rimossi per brevità * / return (
      this.renderProducts ()
    );

    Qui abbiamo aggiunto createProduct nello stato e inizializzato con il valore nullo. La linea onClick = () => this.handleClick (prodotto) invoca il handleClick () metodo quando si fa clic sull'elemento della lista. Il handleClick () metodo aggiorna lo stato di currentProduct

    Ora per visualizzare i dati del prodotto, possiamo renderlo all'interno del componente principale o creare un nuovo componente. Come accennato in precedenza, la suddivisione dell'interfaccia utente in componenti più piccoli è il modo React di fare le cose. Quindi creeremo un nuovo componente e lo chiameremo Prodotto.

    Il componente Product è annidato all'interno del componente Main. Il componente principale passa il suo stato come oggetti di scena. Il componente Product accetta questi oggetti come input e rende le informazioni rilevanti.

    risorse / beni / js / component / main.js

    render () return (/ * I div aggiuntivi sono per gli stili css * / 

    Tutti i prodotti

      this.renderProducts ()
    );

    risorse / beni / js / component / Product.js

    import React, Component da 'react'; / * Componente stateless o componente puro * sintassi product è l'oggetto che distrugge * / const Product = (product) => const divStyle = / * codice omesso per brevità * / // se il prodotto props è null , return Il prodotto non esiste se (! product) return (
    Il prodotto non esiste
    ); // Altro, visualizza il ritorno dei dati del prodotto (

    Product.title

    Descrizione del prodotto

    Stato product.availability? 'Disponibile': 'Esaurito'

    Prezzo: product.price

    ) esportazione del prodotto predefinito;

    L'applicazione dovrebbe essere simile a questa ora:

    Aggiungere un nuovo prodotto

    Abbiamo implementato con successo il front-end corrispondente al recupero di tutti i prodotti e alla loro visualizzazione. Successivamente, abbiamo bisogno di un modulo per aggiungere un nuovo prodotto all'elenco dei prodotti. Il processo di aggiunta di un prodotto potrebbe sembrare un po 'più complesso del semplice recupero dei dati da un'API.

    Ecco cosa penso sia necessario per sviluppare questa funzionalità:

    • Un nuovo componente stateful che rende l'interfaccia utente per un modulo di input. Lo stato del componente contiene i dati del modulo.
    • Al momento dell'invio, il componente figlio passa lo stato al componente principale utilizzando un callback.
    • Il componente principale ha un metodo, per esempio handleNewProduct (), che gestisce la logica per l'avvio di una richiesta POST. Dopo aver ricevuto la risposta, il componente principale aggiorna il suo stato (entrambi this.state.products e this.state.currentProduct

    Non sembra molto complesso, vero? Facciamolo passo dopo passo. Innanzitutto, crea un nuovo componente. Lo chiamerò addProduct

    risorse / attività / js / component / AddProduct.js

    class AddProduct estende Component costruttore (oggetti di scena) super (oggetti di scena); / * Inizializza lo stato. * / this.state = newProduct: title: ", description:", price: 0, availability: 0 // codice Boilerplate per i metodi di binding con "this" this.handleSubmit = this.handleSubmit.bind (this) ; this.handleInput = this.handleInput.bind (this);  / * Questo metodo accetta dinamicamente gli input e lo memorizza nello stato * / handleInput (key, e) / * Duplicando e aggiornando lo stato * / var state = Object.assign (, this.state.newProduct); state [key] = e.target.value; this.setState (newProduct: state);  / * Questo metodo viene richiamato quando viene premuto il pulsante di invio * / handleSubmit (e) // preventDefault impedisce il ricaricamento della pagina e.preventDefault (); / * Una richiamata ai puntelli onAdd. Lo stato corrente * viene passato come parametro * / this.props.onAdd (this.state.newProduct);  render () const divStyle = / * Codice omesso per brevità * / ritorno ( 

    Aggiungi un nuovo prodotto

    / * quando viene premuto il pulsante Submit, il controllo passa a * handleSubmit method * /
    / * Campi di input per prezzo e disponibilità omessi per brevità * /
    ) esportazione predefinito AddProduct;

    Il componente rende fondamentalmente un modulo di input e tutti i valori di input sono memorizzati nello stato (this.state.newProduct). Quindi, sulla sottomissione del modulo, handleSubmit () il metodo viene invocato. Ma addProduct ha bisogno di comunicare le informazioni al genitore, e lo facciamo usando un callback. 

    Il componente principale, che è il genitore, passa un riferimento di funzione come oggetti di scena. Il componente figlio, addProduct nel nostro caso, invoca questi oggetti di scena per informare il genitore della modifica dello stato. Quindi la linea this.props.onAdd (this.state.newProduct); è un esempio di callback che notifica il componente principale del nuovo prodotto. 

    Ora, all'interno del componente principale, dichiareremo come segue:

     

    Il onAdd il gestore di eventi è incatenato al componente handleAddProduct () metodo. Questo metodo ospita il codice per effettuare una richiesta POST al server. Se la risposta indica che il prodotto è stato creato correttamente, lo stato di prodotti e currentProducts è aggiornato. 

     handleAddProduct (product) product.price = Number (product.price); / * API di recupero per la richiesta post * / fetch ('api / products /', method: 'post', / * le intestazioni sono importanti * / intestazioni: 'Accept': 'application / json', 'Content-Type' : 'application / json', body: JSON.stringify (product)) .then (response => return response.json ();) .then (data => // aggiorna lo stato dei prodotti e currentProduct this.setState ((prevState) => (prodotti: prevState.products.concat (dati), currentProduct: data))) 

    Non dimenticare di legare il handleProduct metodo alla classe usando this.handleAddProduct = this.handleAddProduct.bind (this); nel costruttore. Ed ecco la versione finale dell'applicazione:

    Cosa Avanti?

    L'applicazione è incompleta senza le funzionalità di eliminazione e aggiornamento. Ma se hai seguito il tutorial da vicino fino ad ora, dovresti essere in grado di riempire il vuoto senza troppi problemi. Per iniziare, ti ho fornito la logica del gestore di eventi per lo scenario di eliminazione e aggiornamento.

    Logica per l'eliminazione di un prodotto

     handleDelete () const currentProduct = this.state.currentProduct; fetch ('api / products /' + this.state.currentProduct.id, method: 'delete') .then (response => / * Duplica la matrice e filtra l'elemento da eliminare * / var array = this.state.products.filter (function (item) return item! == currentProduct); this.setState (products: array, currentProduct: null);); 

    Logica per l'aggiornamento di un prodotto esistente

    handleUpdate (prodotto) const currentProduct = this.state.currentProduct; fetch ('api / products /' + currentProduct.id, method: 'put', header: 'Accept': 'application / json', 'Content-Type': 'application / json', body: JSON. stringify (product)) .then (response => return response.json ();) .then (data => / * Aggiornamento dello stato * / var array = this.state.products.filter (function (item ) return item! == currentProduct) this.setState ((prevState) => (prodotti: array.concat (prodotto), currentProduct: prodotto))) 

    Quello che devi fare è immergerti, sporcarti le mani e finire l'applicazione usando la logica di cui sopra. Ti suggerirò un suggerimento: il pulsante Elimina dovrebbe idealmente entrare nel componente Prodotto, mentre la funzione di aggiornamento dovrebbe avere un componente a sé stante. Vi incoraggio a raccogliere questa sfida e finire i componenti mancanti.

    Sommario

    Abbiamo fatto molta strada da dove abbiamo iniziato. Innanzitutto, abbiamo creato un'API REST utilizzando il framework Laravel. Quindi, abbiamo discusso le nostre opzioni per la miscelazione di Laravel e React. Infine, abbiamo creato un front-end dell'API utilizzando React. 

    Sebbene ci siamo concentrati principalmente sulla creazione di un'applicazione a pagina singola utilizzando React, è possibile creare widget o componenti montati su elementi specifici nelle viste. React è molto flessibile perché è una libreria e una buona.

    Negli ultimi due anni, React è cresciuto in popolarità. In effetti, sul mercato sono disponibili numerosi articoli disponibili per l'acquisto, la revisione, l'implementazione e così via. Se stai cercando risorse aggiuntive intorno a React, non esitare a verificarle.

    Hai mai provato a sperimentare con Laravel e React? Quali sono i tuoi pensieri? Condividili con noi nei commenti.