Files
roxane/.junie/skills/inertia-react-development/SKILL.md

9.1 KiB

name, description
name description
inertia-react-development Develops Inertia.js v2 React client-side applications. Activates when creating React pages, forms, or navigation; using <Link>, <Form>, useForm, or router; working with deferred props, prefetching, or polling; or when user mentions React with Inertia, React pages, React forms, or React navigation.

Inertia React Development

When to Apply

Activate this skill when:

  • Creating or modifying React page components for Inertia
  • Working with forms in React (using <Form> or useForm)
  • Implementing client-side navigation with <Link> or router
  • Using v2 features: deferred props, prefetching, or polling
  • Building React-specific features with the Inertia protocol

Documentation

Use search-docs for detailed Inertia v2 React patterns and documentation.

Basic Usage

Page Components Location

React page components should be placed in the resources/js/pages directory.

Page Component Structure

export default function UsersIndex({ users }) { return (

Users

    {users.map(user =>
  • {user.name}
  • )}
) }

Client-Side Navigation

Use <Link> for client-side navigation instead of traditional <a> tags:

import { Link, router } from '@inertiajs/react'

Home Users View User

import { Link } from '@inertiajs/react'

Logout

Prefetching

Prefetch pages to improve perceived performance:

import { Link } from '@inertiajs/react'

Users

Programmatic Navigation

import { router } from '@inertiajs/react'

function handleClick() { router.visit('/users') }

// Or with options router.visit('/users', { method: 'post', data: { name: 'John' }, onSuccess: () => console.log('Success!'), })

Form Handling

The recommended way to build forms is with the <Form> component:

import { Form } from '@inertiajs/react'

export default function CreateUser() { return (

{({ errors, processing, wasSuccessful }) => ( <> {errors.name &&
{errors.name}
}

                <input type="email" name="email" />
                {errors.email && <div>{errors.email}</div>}

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

                {wasSuccessful && <div>User created!</div>}
            </>
        )}
    </Form>
)

}

Form Component With All Props

import { Form } from '@inertiajs/react'

{({ errors, hasErrors, processing, progress, wasSuccessful, recentlySuccessful, clearErrors, resetAndClearErrors, defaults, isDirty, reset, submit }) => ( <> {errors.name &&
{errors.name}
}
        <button type="submit" disabled={processing}>
            {processing ? 'Saving...' : 'Save'}
        </button>

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

        {wasSuccessful && <div>Saved!</div>}
    </>
)}

Form Component Reset Props

The <Form> component supports automatic resetting:

  • resetOnError - Reset form data when the request fails
  • resetOnSuccess - Reset form data when the request succeeds
  • setDefaultsOnSuccess - Update default values on success

Use the search-docs tool with a query of form component resetting for detailed guidance.

import { Form } from '@inertiajs/react'

{({ errors, processing, wasSuccessful }) => ( <> {errors.name &&
{errors.name}
}
        <button type="submit" disabled={processing}>
            Submit
        </button>
    </>
)}

Forms can also be built using the useForm helper for more programmatic control. Use the search-docs tool with a query of useForm helper for guidance.

useForm Hook

For more programmatic control or to follow existing conventions, use the useForm hook:

import { useForm } from '@inertiajs/react'

export default function CreateUser() { const { data, setData, post, processing, errors, reset } = useForm({ name: '', email: '', password: '', })

function submit(e) {
    e.preventDefault()
    post('/users', {
        onSuccess: () => reset('password'),
    })
}

return (
    <form onSubmit={submit}>
        <input
            type="text"
            value={data.name}
            onChange={e => setData('name', e.target.value)}
        />
        {errors.name && <div>{errors.name}</div>}

        <input
            type="email"
            value={data.email}
            onChange={e => setData('email', e.target.value)}
        />
        {errors.email && <div>{errors.email}</div>}

        <input
            type="password"
            value={data.password}
            onChange={e => setData('password', e.target.value)}
        />
        {errors.password && <div>{errors.password}</div>}

        <button type="submit" disabled={processing}>
            Create User
        </button>
    </form>
)

}

Inertia v2 Features

Deferred Props

Use deferred props to load data after initial page render:

export default function UsersIndex({ users }) { // users will be undefined initially, then populated return (

Users

{!users ? (
) : (
    {users.map(user => (
  • {user.name}
  • ))}
)}
) }

Polling

Automatically refresh data at intervals:

import { router } from '@inertiajs/react' import { useEffect } from 'react'

export default function Dashboard({ stats }) { useEffect(() => { const interval = setInterval(() => { router.reload({ only: ['stats'] }) }, 5000) // Poll every 5 seconds

    return () => clearInterval(interval)
}, [])

return (
    <div>
        <h1>Dashboard</h1>
        <div>Active Users: {stats.activeUsers}</div>
    </div>
)

}

WhenVisible (Infinite Scroll)

Load more data when user scrolls to a specific element:

import { WhenVisible } from '@inertiajs/react'

export default function UsersList({ users }) { return (

{users.data.map(user => (
{user.name}
))}

        {users.next_page_url && (
            <WhenVisible
                data="users"
                params={{ page: users.current_page + 1 }}
                fallback={<div>Loading more...</div>}
            />
        )}
    </div>
)

}

Common Pitfalls

  • Using traditional <a> links instead of Inertia's <Link> component (breaks SPA behavior)
  • Forgetting to add loading states (skeleton screens) when using deferred props
  • Not handling the undefined state of deferred props before data loads
  • Using <form> without preventing default submission (use <Form> component or e.preventDefault())
  • Forgetting to check if <Form> component is available in your Inertia version