Acceso

Zod, Mejorando la Validación de Formularios en React.

toscadev

@ ToscaDevsJS


Introducción

En el desarrollo de aplicaciones web, la gestión y validación de formularios es una tarea común pero crucial.

En este artículo, vamos a explorar dos bibliotecas poderosas que hacen que esta tarea sea más fácil y eficiente: React Hook Form y Zod.

npm install react-hook-form

npm i @hookform/resolvers

npm i zod

CÓDIGO COMPLETO

Este fragmento de código simplifica en gran medida la tarea de Editar documentos a Firestore en aplicaciones React, lo que puede ser de gran utilidad en tus proyectos.

page.tsx
"use client";

import { zodResolver } from "@hookform/resolvers/zod";
import { useForm, SubmitHandler } from "react-hook-form";
import { z } from "zod";

type Inputs = {
  titulo: string,
  description: string,
  price: string,
  email: string,
};

const schema = z.object({
  titulo: z
    .string()
    .min(2, { message: "El título debe tener al menos 2 caracteres" })
    .max(10, { message: "El título no puede tener más de 10 caracteres" })
    .refine((value) => /^[a-z0-9\s.,]+$/i.test(value), {
      message: "El título solo puede contener letras y números",
    }),
  description: z
    .string()
    .min(10, { message: "La descripción debe tener al menos 10 caracteres" }),
  price: z.number().min(10, { message: "El precio debe ser al menos 10" }),
  email: z.string().email({ message: "El email no es válido" }),
});

export default function Home() {
  const {
    register,
    handleSubmit,
    formState: { errors },
    reset,
    watch,
  } = useForm < Inputs > { resolver: zodResolver(schema) };

  const onSubmit: SubmitHandler<Inputs> = (data) => {
    console.log(data);
    //   reset();
  };

  return (
    <>
      <h1 className="text-center font-bold text-5xl p-5">Fook Form</h1>
      <div className="w-80 m-auto rounded shadow-lg ">
        <form onSubmit={handleSubmit(onSubmit)} className="p-4">
          <div>
            <label htmlFor="Título">Título</label>
            <input
              type="text"
              placeholder="Introduzca el título"
              className="form-control mb-4  dark:bg-slate-800/60 dark:border-slate-700/50 w-full rounded-md border-0 px-3.5 py-2 leading-6"
              {...register("titulo", { required: true })}
            />
          </div>
          <div>
            <label htmlFor="Description">Descripción</label>
            <input
              type="text"
              placeholder="Descripción"
              className="form-control mb-4  dark:bg-slate-800/60 dark:border-slate-700/50 w-full rounded-md border-0 px-3.5 py-2 leading-6"
              {...register("description", { required: true })}
            />
          </div>
          <div>
            <label htmlFor="email">Email</label>
            <input
              type="text"
              placeholder="Introduce el email."
              className="form-control mb-4  dark:bg-slate-800/60 dark:border-slate-700/50 w-full rounded-md border-0 px-3.5 py-2 leading-6"
              {...register("email", { required: true, pattern: /^\S+@\S+$/i })}
            />
          </div>
          <div>
            <label htmlFor="Price">Precio</label>
            <input
              type="number"
              placeholder="Introduce el Precio."
              className="form-control mb-4  dark:bg-slate-800/60 dark:border-slate-700/50 w-full rounded-md border-0 px-3.5 py-2 leading-6"
              {...register("price", { required: true })}
            />
          </div>

          {errors.titulo?.message && (
            <p className="text-red-700">{errors.titulo?.message}</p>
          )}
          {errors.email?.message && (
            <p className="text-red-700">{errors.email?.message}</p>
          )}

          <button className="w-full px-4 py-2 tracking-wide text-white transition-colors duration-200 transform bg-blue-500 rounded-md hover:bg-blue-600 focus:outline-none focus:bg-blue-600">
            Visualizar Producto
          </button>
        </form>

        <p className="">{}</p>
      </div>
      <p className="text-center">{JSON.stringify(watch(), null, 2)}</p>
    </>
  );
}

NOTAS DEL DESARROLLADOR

-Validaciónes: Algunos de los métodos de validación más comunes que se utilizan en los formularios son:


z.string().min(5, { message: "Debe tener 5 o más caracteres" });
z.string().max(5, { message: "Debe tener 5 caracteres o menos" });
z.string().length(5, { message: "Debe tener exactamente 5 caracteres" });
z.string().email({ message: "Dirección de correo electrónico no válida" });
z.string().url({ message: "URL invalida" });
z.string().emoji({ message: "Contiene un carácter que no es emojis" });
z.string().uuid({ message: "UUID no válido" });
z.string().includes("tuna", { message: "Debe incluir tuna" });
z.string().startsWith("https://", { message: "Debe proporcionar una URL segura" });
z.string().endsWith(".com", { message: "Solo se admiten dominios .com" });
z.string().datetime({ message: "¡Cadena de fecha y hora no válida! Debe ser UTC." });
z.string().ip({ message: "Dirección IP inválida" });
z.refine((value) => /^[a-z0-9\s.,]+$/i.test(value), {
      message: "El título solo puede contener letras y números",
    });

Algunos de los métodos de validación más comunes que se utilizan en los formularios son::

-refine: expresiones regulares:

validando para que verifique si el valor del título contiene solo caracteres alfanuméricos, espacios, puntos y comas utilizando una expresión regular.

.refine((value) => /^[a-z0-9\s.,]+$/i.test(value), {
      message: "El título solo puede contener letras y números",
    }),

 a-z0-9 //acepta valores afanuméricos, es decir, letras de la a a la z y números del 0 al 9.
  \s    //acepta espacios en blanco.
  .     //acepta el punto.
  ,     //acepta la coma.
  +     //acepta que se repita una o más veces.



Si te gusto esta guía no dudes en compartirla o sugerir tu opinión. ❤️


Regresar al Blog.

© Copyright 2024 ToscaDevJS.