DEV Community

ccslu
ccslu

Posted on

Form - Next15/React19/ReactHookForm + Zod + useActionState

Respuesta Directa

Puntos clave:

  • Parece probable que la mejor combinación para manejar formularios en React 19 y Next.js 15 sea usar React Hook Form para la gestión y validación del formulario en el cliente, Zod para la validación consistente en cliente y servidor, y useActionState para manejar envíos al servidor.
  • La evidencia sugiere que esta combinación es simple, escalable y amigable para los desarrolladores, reduciendo el código repetitivo y facilitando la integración con componentes UI como Shadcn.
  • Hay cierta controversia sobre si useActionState puede reemplazar completamente React Hook Form, pero parece que usar ambos juntos maximiza la experiencia del usuario y la funcionalidad.

¿Cómo se hacía antes y cómo se hace ahora?

  • Antes, en React, los formularios solían requerir mucho código para manejar estados y validaciones, como se describe en artículos antiguos como Mastering the Art of Forms in React. Ahora, con React 19 y Next.js 15, useActionState simplifica la gestión de envíos y estados, y herramientas como React Hook Form y Zod facilitan la validación, como se detalla en Mastering Forms in Next.js 15 and React 19.

¿Qué es lo más simple, escalable y amigable para desarrolladores (DX)?

  • La combinación de React Hook Form, Zod y useActionState parece ser la más adecuada. React Hook Form reduce el boilerplate al manejar estados y validaciones en el cliente, Zod asegura validaciones consistentes en cliente y servidor, y useActionState facilita envíos al servidor con estados como "pendiente" (isPending), eliminando la necesidad de isSubmitting de React Hook Form en algunos casos.

¿Cómo manejar errores del servidor y validaciones?

  • Para errores del servidor, el servidor puede devolver un objeto con errores, y React Hook Form puede usar setError para mostrarlos en los campos del formulario, integrándose bien con componentes Shadcn. Zod puede usarse en el servidor para validar datos y devolver errores específicos o generales para el formulario.

Un detalle inesperado:

  • useActionState permite que los formularios funcionen incluso sin JavaScript, gracias a la integración con acciones del servidor en Next.js, lo que mejora la accesibilidad y la experiencia sin conexión, algo que no es tan evidente al principio.

Nota Detallada

En esta nota, exploraremos en profundidad cómo manejar formularios en React 19 y Next.js 15, abordando las preocupaciones del usuario sobre simplicidad, escalabilidad, experiencia de desarrollo (DX) y la integración de herramientas como React Hook Form, Zod y useActionState. Analizaremos cómo se hacía antes, cómo se hace ahora, y proporcionaremos una guía paso a paso para resolver las dudas, siguiendo las mejores prácticas actuales.

Contexto Histórico y Evolución

Históricamente, manejar formularios en React implicaba crear estados para cada campo, manejar eventos onChange y validaciones manuales, lo que generaba mucho código repetitivo. Esto se refleja en artículos como Mastering the Art of Forms in React, que datan de 2017 y muestran enfoques tradicionales. Con la evolución de React y Next.js, especialmente en las versiones 19 y 15 respectivamente, las herramientas modernas han simplificado este proceso. El artículo Mastering Forms in Next.js 15 and React 19 destaca cómo useActionState y las acciones del servidor en Next.js han transformado la gestión de formularios, integrándose con validaciones avanzadas y componentes UI.

Análisis de Herramientas y Recomendación

El usuario expresó interés en React Hook Form para evitar crear múltiples estados y boilerplate, y en Zod para validaciones consistentes en cliente y servidor. Además, mencionó useActionState como una alternativa que parece simplificar el manejo de envíos, especialmente con el estado isPending, que podría reemplazar isSubmitting de React Hook Form. También se refirió a Shadcn, diseñado para integrarse con React Hook Form, y a la confusión sobre cómo manejar errores del servidor y validaciones.

React Hook Form y useActionState: ¿Cómo Integrarlos?

useActionState, introducido en React 19, es un hook que actualiza el estado basado en el resultado de una acción de formulario, retornando el estado actual, una acción para el formulario y un indicador isPending. Según la documentación de React (useActionState – React), es ideal para integrarse con acciones del servidor en Next.js, permitiendo mostrar respuestas del servidor antes de la hidratación completa. Esto mejora el rendimiento y la experiencia sin JavaScript, un detalle inesperado que refuerza la accesibilidad.

React Hook Form, por otro lado, es una biblioteca madura para gestionar estados de formularios y validaciones en el cliente, reduciendo el boilerplate. Artículos como How to use react-hook-form with useActionState Hook in Nextjs15 sugieren que ambas herramientas pueden combinarse: React Hook Form maneja la validación en tiempo real y el estado del formulario, mientras que useActionState gestiona el envío al servidor y el estado de la acción.

Por ejemplo, un flujo típico sería:

  1. Definir un esquema Zod para validar datos.
  2. Usar React Hook Form con el esquema Zod para validaciones en el cliente.
  3. En el envío, usar useActionState para llamar a una acción del servidor en Next.js.
  4. La acción del servidor valida los datos con el mismo esquema Zod y retorna errores si es necesario.

Esta combinación parece ser la más simple y escalable, ya que React Hook Form reduce el código repetitivo, Zod asegura consistencia, y useActionState facilita la integración con el servidor.

Validación con Zod: Cliente y Servidor

Zod es una biblioteca de validación de esquemas que puede usarse tanto en el cliente como en el servidor, lo que garantiza consistencia. Por ejemplo, puedes definir un esquema como:

import { z } from 'zod';

const userSchema = z.object({
  name: z.string().min(3),
  email: z.string().email(),
});
Enter fullscreen mode Exit fullscreen mode

En el cliente, React Hook Form puede integrarse con Zod usando el resolver proporcionado por @hookform/resolvers/zod. En el servidor, la acción puede validar los datos entrantes con el mismo esquema y retornar errores si falla. Esto elimina la duplicación de lógica y mejora la mantenibilidad.

Manejo de Errores del Servidor

El usuario se preguntó cómo devolver errores del servidor y mostrarlos, ya sea en campos específicos o a nivel de formulario. Con useActionState, la acción del servidor puede retornar un objeto con errores, como { success: false, errors: { name: 'Nombre requerido' } }. Luego, en el cliente, puedes usar setError de React Hook Form para mostrar estos errores en los campos, integrándose bien con componentes Shadcn, que están diseñados para mostrar errores de React Hook Form (ErrorMessage – React Hook Form).

Para errores generales del formulario (no específicos de un campo), puedes mostrar un mensaje en la interfaz, como un alert o un componente de feedback, usando el estado retornado por useActionState. Esto es útil para mensajes como "Credenciales inválidas", que no corresponden a un campo específico.

Integración con Shadcn y DX

Shadcn, una biblioteca de componentes UI, está diseñada para trabajar con React Hook Form, inferiendo fácilmente errores de validación de Zod en el cliente. Esto mejora la experiencia de desarrollo (DX), ya que reduce la necesidad de escribir código personalizado para mostrar errores. Al combinarlo con useActionState, puedes mantener una experiencia fluida, donde los errores del servidor se integran en la misma interfaz.

Comparativa: ¿React Hook Form o useActionState Solo?

Hay debate sobre si useActionState puede reemplazar completamente React Hook Form. Artículos como Should I Use React useActionState or React Hook Form? sugieren que useActionState es excelente para acciones del servidor, pero React Hook Form ofrece validación en tiempo real y gestión de estado más robusta. La evidencia apunta a que usar ambos juntos es la mejor práctica, especialmente para proyectos complejos, ya que cubren necesidades complementarias.

Guía Paso a Paso

Dada la falta de una guía completa mencionada por el usuario, aquí tienes un flujo sugerido:

  1. Instala las dependencias:

    • npm install react-hook-form @hookform/resolvers/zod zod
  2. Define el esquema Zod:

   import { z } from 'zod';

   const userSchema = z.object({
     name: z.string().min(3, 'Nombre debe tener al menos 3 caracteres'),
     email: z.string().email('Email inválido'),
   });
Enter fullscreen mode Exit fullscreen mode
  1. Crea el formulario con React Hook Form:
   import { useForm, FormProvider } from 'react-hook-form';
   import { zodResolver } from '@hookform/resolvers/zod';

   const FormComponent = () => {
     const methods = useForm({
       resolver: zodResolver(userSchema),
       defaultValues: { name: '', email: '' },
     });

     return (
       <FormProvider {...methods}>
         <form onSubmit={methods.handleSubmit(onSubmit)}>
           {/* Campos del formulario con Shadcn, por ejemplo */}
         </form>
       </FormProvider>
     );
   };
Enter fullscreen mode Exit fullscreen mode
  1. Integra useActionState para el envío:
   import { useActionState } from 'react';

   const [state, formAction, isPending] = useActionState(serverAction, initialState);

   async function serverAction(prevState, formData) {
     const result = await validateAndProcess(formData); // Usa Zod aquí
     if (result.errors) return { success: false, errors: result.errors };
     return { success: true, message: 'Formulario enviado' };
   }
Enter fullscreen mode Exit fullscreen mode
  1. Maneja errores del servidor:
    • Si state contiene errores, usa methods.setError para mostrarlos:
   useEffect(() => {
     if (state.errors) {
       Object.entries(state.errors).forEach(([key, message]) => {
         methods.setError(key, { message });
       });
     }
   }, [state, methods]);
Enter fullscreen mode Exit fullscreen mode
  1. Muestra estados en la UI:
    • Usa isPending para deshabilitar el botón de envío mientras se procesa.
    • Muestra mensajes generales con state.message si es necesario.

Tabla Comparativa: Herramientas y Usos

Herramienta Uso Principal Ventajas Limitaciones
React Hook Form Gestión de estado y validación en cliente Reduce boilerplate, validación en tiempo real, integración con UI Requiere configuración para acciones del servidor
Zod Validación de esquemas en cliente y servidor Consistencia, reutilizable, fuerte tipado Puede ser complejo para esquemas grandes
useActionState Gestión de envíos y estados del servidor Simple, accesible sin JavaScript, isPending integrado Menos control sobre validación en cliente

Conclusión

La combinación de React Hook Form, Zod y useActionState parece ser la más adecuada para formularios en React 19 y Next.js 15, ofreciendo simplicidad, escalabilidad y una excelente experiencia de desarrollo. React Hook Form maneja el cliente, Zod asegura validaciones consistentes, y useActionState facilita la integración con el servidor, incluyendo el manejo de errores y estados. Esta aproximación sigue las mejores prácticas actuales, reduciendo complejidad y mejorando la mantenibilidad.

Citas Clave

Heroku

Built for developers, by developers.

Whether you're building a simple prototype or a business-critical product, Heroku's fully-managed platform gives you the simplest path to delivering apps quickly — using the tools and languages you already love!

Learn More

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

DEV is better (more customized, reading settings like dark mode etc) when you're signed in!

Okay