All skills
asyrafhussin avatar

/laravel-inertia-react

@ac26821

Laravel + Inertia.js + React integration patterns. Use when building Inertia page components, handling forms with useForm, managing shared data, or implementing persistent layouts. Triggers on tasks involving Inertia.js, page props, form handling, or Laravel React integration.

Use this Skill: https://skilld.dev/gh/asyrafhussin/agent-skills/laravel-inertia-react

This session only. Nothing lands on disk.

rulesform-useform-basic.md

≈1.4k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Form useForm Hook

The useForm hook is Inertia's primary way to handle forms. It provides automatic form state management, error handling, processing state, and seamless integration with Laravel validation.

Incorrect

// ❌ Manual state management
import { useState } from 'react'
import { router } from '@inertiajs/react'

function CreatePost() {
  const [title, setTitle] = useState('')
  const [body, setBody] = useState('')
  const [errors, setErrors] = useState({})
  const [processing, setProcessing] = useState(false)

  const handleSubmit = async (e) => {
    e.preventDefault()
    setProcessing(true)

    router.post('/posts', { title, body }, {
      onError: (errors) => setErrors(errors),
      onFinish: () => setProcessing(false),
    })
  }

  return (
    <form onSubmit={handleSubmit}>
      {/* ... */}
    </form>
  )
}

Correct

// ✅ Using useForm hook
import { useForm } from '@inertiajs/react'
import { FormEvent } from 'react'

interface FormData {
  title: string
  body: string
  category_id: string
}

export default function CreatePost() {
  const { data, setData, post, processing, errors, reset, clearErrors } =
    useForm<FormData>({
      title: '',
      body: '',
      category_id: '',
    })

  const handleSubmit = (e: FormEvent) => {
    e.preventDefault()

    post(route('posts.store'), {
      onSuccess: () => {
        reset()  // Clear form on success
      },
    })
  }

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label htmlFor="title">Title</label>
        <input
          id="title"
          type="text"
          value={data.title}
          onChange={(e) => setData('title', e.target.value)}
          onFocus={() => clearErrors('title')}
        />
        {errors.title && <span className="text-red-500">{errors.title}</span>}
      </div>

      <div>
        <label htmlFor="body">Body</label>
        <textarea
          id="body"
          value={data.body}
          onChange={(e) => setData('body', e.target.value)}
        />
        {errors.body && <span className="text-red-500">{errors.body}</span>}
      </div>

      <button type="submit" disabled={processing}>
        {processing ? 'Creating...' : 'Create Post'}
      </button>
    </form>
  )
}

useForm Methods

const {
  data,           // Current form data
  setData,        // Update form data
  post,           // POST request
  put,            // PUT request
  patch,          // PATCH request
  delete: destroy,// DELETE request (renamed to avoid keyword)
  processing,     // Is form submitting?
  errors,         // Validation errors from Laravel
  reset,          // Reset form to initial values
  clearErrors,    // Clear specific or all errors
  isDirty,        // Has form been modified?
  transform,      // Transform data before submit
  setError,       // Set custom error
  recentlySuccessful, // Was last submit successful?
} = useForm({
  // Initial values
})

Setting Data

// Single field
setData('title', 'New Title')

// Multiple fields
setData({
  title: 'New Title',
  body: 'New Body',
})

// Using callback (access previous data)
setData((prevData) => ({
  ...prevData,
  title: prevData.title.toUpperCase(),
}))

// Nested data
setData('author.name', 'John')

HTTP Methods

// POST - Create
post(route('posts.store'))

// PUT - Full update
put(route('posts.update', post.id))

// PATCH - Partial update
patch(route('posts.update', post.id))

// DELETE
destroy(route('posts.destroy', post.id), {
  onBefore: () => confirm('Are you sure?'),
})

Options

post(route('posts.store'), {
  // Preserve state on success
  preserveState: true,

  // Preserve scroll position
  preserveScroll: true,

  // Replace history instead of push
  replace: true,

  // Callbacks
  onBefore: (visit) => {
    // Return false to cancel
  },
  onStart: (visit) => {},
  onProgress: (progress) => {
    // For file uploads
    console.log(progress.percentage)
  },
  onSuccess: (page) => {
    reset()
  },
  onError: (errors) => {
    // Handle errors
  },
  onCancel: () => {},
  onFinish: () => {
    // Always called (success or error)
  },
})

Edit Form Pattern

interface Post {
  id: number
  title: string
  body: string
}

interface Props {
  post: Post
}

export default function Edit({ post }: Props) {
  // Initialize with existing data
  const { data, setData, put, processing, errors } = useForm({
    title: post.title,
    body: post.body,
  })

  const handleSubmit = (e: FormEvent) => {
    e.preventDefault()
    put(route('posts.update', post.id))
  }

  return (
    <form onSubmit={handleSubmit}>
      {/* Form fields */}
      <button disabled={processing}>
        {processing ? 'Saving...' : 'Save Changes'}
      </button>
    </form>
  )
}

Transform Data Before Submit

const { data, setData, transform, post } = useForm({
  remember: false,
  email: '',
  password: '',
})

// Transform before sending
transform((data) => ({
  ...data,
  remember: data.remember ? 'on' : '',
}))

Benefits

  • Automatic error handling from Laravel
  • Processing state management
  • Form reset functionality
  • TypeScript support
  • Seamless Laravel integration

Source: SKILL.md on GitHub

1 warning16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill provides a comprehensive set of best practices and patterns for building applications with Laravel, Inertia.js, and React. The content consists of architectural guidance and code examples that follow official framework standards and do not exhibit any malicious behavior or security risks.

  • Socket16d

    1 alert: gptAnomaly

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    30 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at ac26821. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated 7 months ago
Other metadata
metadata
{
  "author": "AsyrafHussin",
  "version": "1.0.2",
  "laravelVersion": "13.x",
  "phpVersion": "8.3+"
}

README badge

README badge for asyrafhussin/agent-skills/laravel-inertia-react