Integrando React e InertiaJS con TypeScript

Jose Nucamendi

José Nucamendi

27 May, 2024

Inertiajs

Bienvenido a este completo tutorial donde exploraremos la poderosa combinación de Laravel, InertiaJS, TypeScript y React. Al final de esta guía, tendrás una sólida comprensión de cómo construir aplicaciones web modernas y robustas utilizando estas tecnologías.

¿Por qué este stack?

Laravel es un framework PHP conocido por su elegante sintaxis, amplio conjunto de características y fuerte apoyo de la comunidad. Simplifica el proceso de desarrollo con herramientas y bibliotecas para el enrutamiento, la autenticación y la gestión de bases de datos, por lo que es una opción ideal para el desarrollo de backend.


InertiaJS tiende un puente entre los frameworks tradicionales del lado del servidor y las modernas aplicaciones de una sola página (SPA). Permite crear aplicaciones dinámicas de una sola página sin la complejidad de una solución totalmente del lado del cliente. InertiaJS aprovecha la potencia de la renderización del lado del servidor a la vez que proporciona una experiencia de usuario fluida.


TypeScript, un superconjunto de JavaScript, añade tipado estático al código, lo que permite detectar errores en una fase temprana del proceso de desarrollo. Mejora la calidad del código, la capacidad de mantenimiento y la escalabilidad, por lo que es la opción preferida para proyectos de mayor impacto.


React es una potente biblioteca de JavaScript para crear interfaces de usuario. Su arquitectura basada en componentes y su eficiente renderización la hacen perfecta para crear aplicaciones web interactivas y dinámicas.



En primer lugar, tenemos que crear un proyecto Laravel utilizando:


composer create-project laravel/laravel example


Configuración del servidor


Instale el adaptador del lado del servidor usando Composer.


composer require inertiajs/inertia-laravel



En la ruta resources/views, necesitamos crear el archivo app.blade.php e incluir el siguiente contenido:


<!DOCTYPE html>

<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
    @vite('resources/ts/app.tsx')
    @inertiaHead
</head>

<body>
@inertia
</body>
</html>



Como se menciona en la documentación oficial, Inertia usará por defecto el archivo app.blade.php localizado en la carpeta resources/views. Sin embargo, puedes cambiar esto si lo deseas usando el método Inertia::setRootView().


Ahora instalaremos el middleware de Inertia usando Composer:


php artisan inertia:middleware



Una vez publicado el middleware, añada el middleware HandleInertiaRequests al grupo de middleware web en el archivo bootstrap/app.php de su aplicación.


use App\Http\Middleware\HandleInertiaRequests;


<?php 


use App\Http\Middleware\HandleInertiaRequests;


$app = new Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);


...other singleton instances


$app->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [
        HandleInertiaRequests::class,
    ]);
})


return $app;


Configuración del lado del cliente


En primer lugar, tendrás que instalar el framework que vayas a integrar con InertiaJS. En nuestro caso, usaremos React. Para ello, ejecuta el siguiente comando npm:


npm install @inertiajs/react



Para evitar errores con TypeScript, necesitarás instalar las siguientes dependencias:


npm install @types/react @types/react-dom typescript



Ahora, vamos a inicializar nuestra aplicación Inertia.js. Para ello, crearemos el archivo resources/ts/app.tsx. Es importante mantener el orden de nuestros directorios para que podamos trabajar eficientemente. También en esta parte, podemos definir diseños predeterminados para ciertas páginas.


import "../css/app.css";
import { createInertiaApp } from "@inertiajs/react";
import { createRoot } from "react-dom/client";
import React from "react";
import Layout from "./layouts/main";

createInertiaApp({
    resolve: (name) => {
        const pages = import.meta.glob("./pages/**/*.tsx", { eager: true });
        let page: any = pages[`./pages/${name}.tsx`];
        page.default.layout =
            page.default.layout || ((page: any) => <Layout children={page} />);

        return page;
    },
    setup({ el, App, props }) {
        createRoot(el).render(<App {...props} />);
    },
}).then((r) => {});



Si es necesario, puedes cambiar el ID de raíz:


createInertiaApp({
  id: 'my-app',
  // ...
})



En nuestro vite.config.js, necesitamos definir los recursos para cargar la aplicación.


import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
   plugins: [

     laravel({

        input: ['resources/css/app.css', 'resources/ts/app.tsx'],

        refresh: true,

     }),

 ],
});



Para la parte de estilo, usaremos Tailwind CSS. El archivo app.css debe crearse en resources/css.


@tailwind base;
@tailwind components;
@tailwind utilities;



Opcional: puedes agregar una biblioteca Linter para mantener el orden en tu equipo.


npm install eslint prettier


Vamos a comenzar


Ahora podemos crear nuestros archivos de aplicación.


Primero, debes crear el archivo main.tsx en la carpeta resources/ts/layouts de la siguiente manera:


import React from "react";

export default function Layout({ children }: { children: React.ReactNode }) {

    return (

        <main className="bg-black-base text-white">

            <div className="flex items-center justify-center">

                <div className="flex flex-col border w-full max-w-md h-screen">

                    <div className="flex-grow">{children}</div>

                    <div className="h-20 border"></div>

                </div>

            </div>

        </main>

    );
}



Luego necesitamos crear el archivo index.tsx en la carpeta resources/ts/pages de la siguiente manera:


import React from "react";

const Index = () => {

    const [counter, updateCounter] = useState<number>(0);
    return (<span className='m-1 p-1 bg-green text-white' onClick={() => updateCounter(prevState => prevState + 1)}>
              You have clicked this span {counter} times!
           </span>);
};

export default Index;



Ahora necesitamos crear la ruta Laravel que renderizará el contenido de nuestra aplicación InertiaJS. Para hacer esto, navega hasta el archivo routes/web.php

Route::get('/', function () {
    return \Inertia\Inertia::render('index', []);
});



En este caso, 'index' es el nombre de la página que declaramos en la siguiente ruta: resources/ts/pages/index.tsx. Este enfoque es similar a las vistas de Laravel, ya que también puede adjuntar colecciones de datos y usarlas en la interfaz fácilmente sin la necesidad de solicitudes asincrónicas. Puedes hacer esto desde un controlador si es necesario. Pero lo haremos de esta manera para simplificar el proceso.


Mientras concluimos, me alegra que hayamos podido explicar cómo configurar Inertia.js con React en su proyecto. Desde la integración de TypeScript hasta la configuración de rutas y diseños, hemos cubierto los pasos esenciales para comenzar. Recuerda, mantener la coherencia con herramientas como ESLint y Prettier puede agilizar el desarrollo. Si encuentra algún obstáculo en el camino, no dude en comunicarse.


¡Feliz programación y que tu proyecto florezca con el poder de Inertia.js y React!


Referencias
Inertia.js. (2024). The Modern Monolith. Obtenido en Mayo 22, 2024, desde InertiaJS