posts/jwuaDZrWc3MRZGMcb3GPlgoqHO5rWmoLCS92Z3Ys.png

Laravel Precognition con React: validación en vivo usando FormRequest (Laravel 12)

Implementa validación en vivo en React sin duplicar reglas: Laravel Precognition ejecuta middleware y FormRequest sin correr el controller.

¿Qué es Precognition y por qué importa?

Precognition “anticipa” el resultado de una request HTTP futura: Laravel ejecuta el pipeline normal (middleware + resolución de dependencias + FormRequest validation) pero no ejecuta el método del controlador.

Eso permite:

  • Validar campo por campo (live validation).

  • Reutilizar tus reglas reales del backend.

  • Evitar flows raros tipo “submit para ver errores”.

Arquitectura mental (simple)

  1. El usuario escribe en un input (React).

  2. En vez de “submit”, el frontend dispara una precognitive request (debounced).

  3. Laravel valida con tu FormRequest.

  4. Regresa errores por campo y el frontend los pinta.

Backend (Laravel 12): ruta + middleware + FormRequest

1) Crea tu FormRequest

php artisan make:request StoreUserRequest

app/Http/Requests/StoreUserRequest.php

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreUserRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'name' => ['required', 'string', 'min:3', 'max:120'],
            'email' => ['required', 'email', 'max:190', 'unique:users,email'],
            'password' => ['required', 'string', 'min:8'],
        ];
    }
}

2) Activa Precognition en la ruta

En la doc oficial, Laravel indica que agregues

HandlePrecognitiveRequests
al endpoint que quieres validar.

routes/web.php

<?php

use App\Http\Requests\StoreUserRequest;
use Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests;
use Illuminate\Support\Facades\Route;

Route::post('/users', function (StoreUserRequest $request) {
    // En requests precognitivas NO se ejecuta este bloque (controller/closure).
    // En submit normal, sí.
    // Aquí harías: User::create([...])
})->middleware([HandlePrecognitiveRequests::class]);

En producción normalmente esto va en un Controller, pero el punto es el mismo: middleware + FormRequest.

Frontend (React): opción A — “React puro” con
laravel-precognition-react

La documentación oficial muestra el flujo con React usando

laravel-precognition-react
y
useForm
.

1) Instala

npm install laravel-precognition-react

2) Form React completo (live validation por blur)

resources/js/Pages/Users/Create.jsx

import React from 'react'
import { useForm } from 'laravel-precognition-react'

export default function CreateUser() {
  const form = useForm('post', '/users', {
    name: '',
    email: '',
    password: '',
  })

  const submit = (e) => {
    e.preventDefault()
    form.submit()
  }

  return (
    <form onSubmit={submit} className="space-y-4">
      <div>
        <label>Nombre</label>
        <input
          value={form.data.name}
          onChange={(e) => form.setData('name', e.target.value)}
          onBlur={() => form.validate('name')}
        />
        {form.invalid('name') && <div>{form.errors.name}</div>}
      </div>

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

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

      {form.validating && <p>Validando...</p>}

      <button disabled={form.processing || form.hasErrors}>
        Crear usuario
      </button>
    </form>
  )
}

Por qué

onBlur
? La doc sugiere setear data en
change
y validar en
blur
para no spamear requests en cada tecla.

Ajusta el debounce (si quieres)

form.setValidationTimeout(500) // ms

Frontend (Inertia + React): opción B — “ya viene integrado” (Inertia 2.3+)

Laravel (docs) y la comunidad reportan que Inertia 2.3 trae soporte integrado de Precognition en Forms, sin paquetes extra.

Recomendación práctica:

  • Si tu stack es Laravel + Inertia + React starter kit, revisa tu versión de Inertia.

  • Si estás en 2.3+, usa el soporte nativo (menos dependencias).

  • Si estás en versión anterior, puedes usar el approach de

    laravel-precognition-react
    o actualizar.

Casos reales y tips (lo que sí te pega en proyectos)

1) “Precognition no ejecuta controller”

Esto es clave: sirve para validar, no para “probar lógica de negocio”. Laravel ejecuta middleware + valida FormRequest, pero no corre el método final.

✅ Úsalo para:

  • Reglas de

    rules()

  • Reglas condicionales de validación

  • unique
    ,
    exists
    , formatos, etc.

⚠️ No lo uses esperando:

  • Cálculos de totales

  • Side effects (guardar algo, descontar inventario, etc.)

2) Validación de arrays (tags, roles, permissions)

Precognition soporta escenarios de validación más complejos (arrays), pero en UI conviene mapear errores por índice (

permissions.0
,
permissions.1
). (Si te pasa en Inertia, se ha discutido como “edge case” en issues recientes).

3) File uploads

Con archivos suele ser mejor:

  • Validar primero campos básicos

  • Al seleccionar archivo:

    forgetError('avatar')
    y validar solo cuando tenga sentido
    (la doc menciona limpiar errores para subsets).

Comparte esta publicación

0 comentarios

Únete a la conversación y comparte tu experiencia.

Dejar un comentario

Comparte dudas, propuestas o mejoras para la comunidad.

Publicaciones relacionadas

Contenido seleccionado para continuar aprendiendo.