Skip to content

Instantly share code, notes, and snippets.

@LanciWeb
Created November 21, 2023 17:45
Show Gist options
  • Select an option

  • Save LanciWeb/eaec72c85cb0860b4dc876bb550c26d8 to your computer and use it in GitHub Desktop.

Select an option

Save LanciWeb/eaec72c85cb0860b4dc876bb550c26d8 to your computer and use it in GitHub Desktop.
Inertia JS Notes

FAQs

Cos'è Inertia.JS?

Inertia NON è un framework JS e non è inteso a sostituirne uno.

Inertia è una libreria JavaScript che ci permette di utilizzare Vue, React o Svelte all'interno di un qualsiasi backend, creando un'esperienza da SPA, ma senza le complessità tipiche della SPA.

In altre parole, tu continui ad utilizzare i pattern e il routing del tuo framework di backend preferito, ma poi a frontend ti ritrovi con la potenza di un framework JS moderno.

Nota: Inertia è cucito attorno a Laravel ma non è legato strettamente a Laravel, ma ha per Laravel (e per Rails) degli adaptors ufficiali che ne rendono facile l'implementazione.



Come funziona?

Di fatto si tratta di una libreria di routing client side!

Grazie al componente <Link> (che wrappa un normale <a>), inertia intercetta la richiesta e invece di ricaricare la pagina, invia la richiesta via Ajax.

Nota: Si può anche navigare programmaticamente con router.visit()

Lo fa tramite axios, che peraltro è già configurato con l'occorrente (per esempio gestisce anche il csrf token) e ha un header X-Inertia: true.

Il server poi invece di renderizzare e restituire una pagina HTML come di consueto, risponde con un JSON contenente il nome del componente JS da utilizzare ed eventuali dati necessari al componente, che verranno ricevuti come props!

Nota: Si tratta tecnicamente di hydration

Inoltre, grazie a Ziggy, possiamo usare i nomi delle rotte in stile Laravel!



Posso usare Typescript?

Sì, ma è in fase sperimentale



Come posso indicare informazioni meta per il SEO?

Inertia mette a disposizione un componente <Head> all'interno del quale possiamo personalizzare la head di ogni singola pagina.



Come mantengo i dati tra una pagina e l'altra?

In due modi:

  • Tramite Shared Layouts possiamo mantenere lo state tra una pagina e l'altra dello stesso layout, in quanto il layout è un componente padre, pertanto al cambio pagina abbiamo un reload parziale ma lo state rimane intoccato.

  • Tramite l' HandleInertiaRequest middleware. In cui passiamo i dati che vogliamo persistere tra tutte le pagine. Questi dati vengono recuperati con l'hook usePage()



Che differenza c'è con Livewire?

Livewire usa Blade, non React/Vue/Svelte





Punti chiave

<Link> Component

Come detto è un wrapper del tag <a> che intercetta la richiesta e invece di ricaricare la pagina, invia la richiesta via Ajax.

Lo fa tramite axios, che peraltro è già configurato con l'occorrente (per esempio gestisce anche il csrf token) e ha un header X-Inertia: true.

as prop

Ci permette di visualizzare il Link come tag <button>.

href prop

Ci permette di passare l'indirizzo e se abbiamo anche Ziggy possiamo anche utilizzare l'helper route, come faremmo in Laravel.

method prop

Uno dei grandi punti di forza: grazie a method possiamo trasformare un button in un form coi metodi PUT, PATCH o DELETE!

preserveScroll prop

Ci permette di mantenere lo scroll

onBefore prop

Ci permette di chiamare una callback da eseguire prima della chiamata!

Visit Options

Queste sono le visit options che troviamo sulla doc in Manual Visits e che sono condivise con router.visit e con useForm

Esempio in Courses/Index.js

<Link href={route('courses.publish', c.id)} as="button" method="patch" preserveScroll>


useForm hook

Si tratta di un helper utilissimo per i form, che ci mette a disposizione tutta una serie di metodi e proprietà per semplificare la gestione dei form stessi.

Http methods

Possiamo estrarre da use form tutti i metodi HTTP:

const { submit, get, post, put, patch, delete: destroy } = useForm({ ... })

submit(method, url, options)
get(url, options)
post(url, options)
put(url, options)
patch(url, options)
destroy(url, options)

Visit Options

Nelle options, oltre ai dati da inviare, vengono accettate tutte le visitOptions, come preserveScroll, preserveState, onSuccess ecc

data

Ha al suo interno tutti i dati del form in tempo reale.

Validazione con errors

Una delle migliori feature è errors che riceve e raccoglie automaticamente l'errorBag di Laravel!

const { data, errors } = useForm({ ... })
<input type="text" value="{data.label}">

<InputError message="{errors.label}" />

Altre utilities

  • hasErrors
  • clearErrors
  • reset
  • setDefaults
  • isDirty

transform

Se vogliamo modificare i dati prima di inviarli possiamo usare transform

const { transform } = useForm({ ... })

transform((data) => ({
  ...data,
  remember: data.remember ? 'on' : '',
}))

processing

Possiamo sapere in ogni momento se il form è in fase di invio

const { processing } = useForm({ ... })

<button type="submit" disabled={processing}>Submit</button>

Upload progress

Se facciamo upload di file, possiamo persino sapere la percentuale di completamento dell'upload

const { progress } = useForm({ ... })

{progress && (
  <progress value={progress.percentage} max="100">
    {progress.percentage}%
  </progress>
)}


Shared data

HandleInertiaRequest

Per condividere i dati, bisogna usare il middleware HandleInertiaRequest. Questo middleware intercetta tutte le richieste di Inertia e ci permette, tramite il metodo share, di passare dei dati visibili a tutte le pagine

Inertia::share()

In alternativa, possiamo usare il metodo statico sharedi Inertia:

// Synchronously...
Inertia::share('appName', config('app.name'));

// Lazily...
Inertia::share('user', fn (Request $request) => $request->user()
    ? $request->user()->only('id', 'name', 'email')
    : null
);

usePage

Per recuperare i dati condivisi, possiamo usare l'hook usePage, all'interno delle cui props troveremo tutti gli shared data.

Nota: La documentazione non lo specifica ma se la pagina non ha un layout, i dati condivisi arrivano direttamente come props, senza bisogno di usePage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment