14- Conoce y aprende a usar Inertia.js junto con React

 

 Conoce y aprende a usar Inertia.js junto con React

Introducción

En este tutorial vamos a explorar el stack Laravel + Inertia.js + React, una alternativa moderna al stack Vue que hemos estado usando. Aprenderemos a configurar el entorno, los componentes principales y cómo React se integra con Inertia para crear aplicaciones SPA.


¿Qué es Inertia.js con React?

Inertia.js es un puente que conecta el backend (Laravel) con el frontend, y funciona tanto con Vue como con React . La experiencia con React es muy similar: sigues usando controladores de Laravel para renderizar páginas, pero en lugar de componentes Vue, utilizas componentes React.

Diferencias clave entre React y Vue en Inertia

AspectoVueReact
Componentes.vue files.jsx o .tsx files
PropsdefinePropsProps de función/componente
Estadoref, reactiveuseState, useReducer
Efectoswatch, computeduseEffect, useMemo
Enrutamiento<Link><Link> (mismo componente)
Metadatos<Head><Head> (mismo componente)

Paso 1: Configurar Inertia con React

1.1 Instalación del adapter de Laravel

Primero, instala el adapter de Inertia para Laravel:

bash
composer require inertiajs/inertia-laravel

1.2 Configurar el root template

Crea resources/views/app.blade.php - este será el template raíz que se carga en la primera visita :

blade
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
    <title>Mi Portafolio</title>
    @vite('resources/js/app.jsx')
    @inertiaHead
</head>
<body>
    @inertia
</body>
</html>

1.3 Instalar dependencias de React

bash
npm install react react-dom @inertiajs/react @vitejs/plugin-react

1.4 Configurar Vite para React

Actualiza vite.config.js:

javascript
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/js/app.jsx'],
            refresh: true,
        }),
        react(),
    ],
});

1.5 Crear el punto de entrada de React

Crea resources/js/app.jsx:

jsx
import { createRoot } from 'react-dom/client';
import { createInertiaApp } from '@inertiajs/react';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';

createInertiaApp({
    resolve: (name) => resolvePageComponent(
        `./Pages/${name}.jsx`,
        import.meta.glob('./Pages/**/*.jsx')
    ),
    setup({ el, App, props }) {
        const root = createRoot(el);
        root.render(<App {...props} />);
    },
});

Paso 2: Instalar Jetstream con React

Laravel Jetstream oficialmente usa Vue por defecto, pero hay varias alternativas para usar React:

Opción 1: Usar un starter kit comunitario

El kit adrum/laravel-jetstream-react-typescript proporciona una base moderna con React 19, TypeScript y HeadlessUI :

bash
laravel new my-app --using=adrum/laravel-jetstream-react-typescript

Opción 2: Convertir Jetstream Vue a React

Si ya tienes Jetstream instalado con Vue, puedes usar laravel-jetstream-react para convertir los componentes :

bash
composer create-project laravel/laravel myapp
cd myapp
composer require laravel/jetstream
php artisan jetstream:install inertia
npx laravel-jetstream-react@latest install

Opción 3: Usar un starter kit con React y Fortify

Algunos paquetes como particle-academy/fancy-starter-kit usan Laravel Fortify en lugar de Jetstream, con React 19 y Tailwind v4 :

bash
laravel new my-app --using=particle-academy/fancy-starter-kit

Paso 3: Componentes principales de Inertia en React

3.1 El componente <Head>

Para establecer el título y meta tags de la página :

jsx
import { Head } from '@inertiajs/react';

export default function Welcome() {
    return (
        <>
            <Head>
                <title>Mi Portafolio - Inicio</title>
                <meta name="description" content="Bienvenido a mi portafolio profesional" />
            </Head>
            <div>
                <h1>Bienvenido</h1>
            </div>
        </>
    );
}

3.2 El componente <Link>

Para navegación SPA sin recargar la página :

jsx
import { Link } from '@inertiajs/react';

export default function Navigation() {
    return (
        <nav>
            <Link href="/" className="nav-link">Inicio</Link>
            <Link href="/projects" className="nav-link">Proyectos</Link>
            <Link href="/about" className="nav-link">Sobre mí</Link>
        </nav>
    );
}

3.3 El hook usePage()

Para acceder a datos compartidos desde el backend :

jsx
import { usePage } from '@inertiajs/react';

export default function Dashboard() {
    const { auth } = usePage().props;
    
    return (
        <div>
            <h1>Bienvenido, {auth.user.name}</h1>
        </div>
    );
}

Nota: usePage() solo funciona en componentes funcionales. Si usas componentes de clase, necesitas usar un Higher-Order Component (HOC) o migrar a componentes funcionales .

3.4 Recibir props desde el backend

Puedes recibir props directamente en el componente :

jsx
// En el controlador de Laravel
return Inertia::render('Projects/Index', [
    'projects' => Project::all(),
    'skills' => Skill::all()
]);

// En el componente React
export default function ProjectsIndex({ projects, skills }) {
    return (
        <div>
            <h2>Proyectos</h2>
            {projects.map(project => (
                <div key={project.id}>{project.title}</div>
            ))}
        </div>
    );
}

Paso 4: Crear una página de bienvenida con React

Crea resources/js/Pages/Welcome.jsx:

jsx
import { Head, Link, usePage } from '@inertiajs/react';

export default function Welcome() {
    const { auth } = usePage().props;
    const user = auth?.user;

    return (
        <>
            <Head title="Inicio - Mi Portafolio" />

            <div className="min-h-screen bg-gray-100">
                {/* Barra de navegación */}
                <nav className="bg-white shadow">
                    <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
                        <div className="flex justify-between h-16 items-center">
                            <div className="flex items-center">
                                <span className="text-xl font-bold">Mi Portafolio</span>
                            </div>

                            <div className="flex items-center space-x-4">
                                {user ? (
                                    <Link href="/dashboard" className="text-gray-700 hover:text-gray-900">
                                        Dashboard
                                    </Link>
                                ) : (
                                    <>
                                        <Link href="/login" className="text-gray-700 hover:text-gray-900">
                                            Iniciar Sesión
                                        </Link>
                                        <Link href="/register" className="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700">
                                            Registrarse
                                        </Link>
                                    </>
                                )}
                            </div>
                        </div>
                    </div>
                </nav>

                {/* Contenido principal */}
                <div className="py-12">
                    <div className="max-w-7xl mx-auto sm:px-6 lg:px-8">
                        <div className="bg-white overflow-hidden shadow-xl sm:rounded-lg p-8">
                            <h1 className="text-4xl font-bold text-gray-900">
                                ¡Bienvenido a Mi Portafolio!
                            </h1>
                            <p className="mt-4 text-lg text-gray-600">
                                Este es el inicio de tu portafolio profesional con Laravel, Inertia y React.
                            </p>
                        </div>
                    </div>
                </div>
            </div>
        </>
    );
}

Paso 5: Diferencias sintácticas clave

5.1 Props y estado

Vue:

vue
<script setup>
const props = defineProps(['user']);
const count = ref(0);
</script>

React:

jsx
export default function Component({ user }) {
    const [count, setCount] = useState(0);
    // ...
}

5.2 Componentes reutilizables

Vue:

vue
<template>
    <div class="card">
        <slot />
    </div>
</template>

React:

jsx
export default function Card({ children }) {
    return <div className="card">{children}</div>;
}

5.3 Eventos y formularios

Vue:

vue
<template>
    <button @click="handleClick">Click</button>
    <input v-model="form.name" />
</template>

React:

jsx
export default function Form() {
    const [name, setName] = useState('');
    
    return (
        <>
            <button onClick={handleClick}>Click</button>
            <input value={name} onChange={e => setName(e.target.value)} />
        </>
    );
}

Paso 6: Crear un componente Section reutilizable

Crea resources/js/Components/Section.jsx:

jsx
export default function Section({ 
    children, 
    background = 'white', 
    text = 'gray-800',
    minHeight = false 
}) {
    return (
        <section className={`px-12 py-16 bg-${background} text-${text} ${minHeight ? 'min-h-screen' : ''}`}>
            <div className="max-w-7xl mx-auto">
                {children}
            </div>
        </section>
    );
}

Y su uso en una página:

jsx
import Section from '@/Components/Section';

export default function Home() {
    return (
        <Section background="gray-800" text="white" minHeight>
            <h1 className="text-4xl font-bold">Hola, soy Juan</h1>
            <p className="text-xl">Software Engineer</p>
        </Section>
    );
}

Paso 7: Manejo de formularios con React

Inertia proporciona el hook useForm para manejar formularios de manera similar a Vue:

jsx
import { useForm } from '@inertiajs/react';

export default function ProjectForm() {
    const { data, setData, post, processing, errors } = useForm({
        title: '',
        description: '',
    });

    const handleSubmit = (e) => {
        e.preventDefault();
        post('/projects');
    };

    return (
        <form onSubmit={handleSubmit}>
            <div>
                <label>Título</label>
                <input
                    type="text"
                    value={data.title}
                    onChange={e => setData('title', e.target.value)}
                />
                {errors.title && <span className="text-red-600">{errors.title}</span>}
            </div>

            <div>
                <label>Descripción</label>
                <textarea
                    value={data.description}
                    onChange={e => setData('description', e.target.value)}
                />
                {errors.description && <span className="text-red-600">{errors.description}</span>}
            </div>

            <button type="submit" disabled={processing}>
                {processing ? 'Guardando...' : 'Guardar Proyecto'}
            </button>
        </form>
    );
}

Resumen

✅ Aprendimos a configurar Inertia con React en Laravel
✅ Exploramos las opciones para usar Jetstream con React
✅ Conocimos los componentes principales: <Head>, <Link> y usePage()
✅ Vimos las diferencias sintácticas entre Vue y React
✅ Creamos componentes reutilizables como Section
✅ Implementamos manejo de formularios con useForm

¡Excelente trabajo! Ahora tienes las bases para construir aplicaciones Laravel + Inertia con React. Aunque el stack Vue es el más común en el ecosistema Laravel, React es una alternativa igualmente válida y potente.


Recursos adicionales


¿Tienes dudas sobre cómo usar React con Inertia? Revisa la documentación oficial o consulta los foros de la comunidad para resolver problemas específicos

Comentarios

Entradas más populares de este blog

Tareas con Laravel + Inertia + Jetstream

HACER CAMBIOS-AL EJEMPLO POR DEFECTO

Laravel + Inertia - ejemplo