Botón para abrir el Menú Botón para cerrar el Menú
Logo da empresa Alura
Iniciar Sesión Nuestros Planes
Formaciones Conoce a Luri
  • Programación _
  • Front End _
  • Data Science _
  • DevOps _
  • Innovación y Gestión _
Artículos de Tecnología > Front-end

React: validación de formulario con React Hook Form

Neilton Seguins
Neilton Seguins
26 de Janeiro

Compartir

Mira este artículo:
  1. ¿Cuál es la diferencia entre componentes controlados y no controlados?
  2. Componentes no controlados
  3. Componentes controlados
  4. Forma de React Hook Form
  5. Componentes personalizados
  6. Integración con bibliotecas de UI

capa

¿Alguna vez has necesitado validar y administrar cada campo de datos en formularios con React ?

Imagine la situación: está navegando por un proyecto y se enfrenta con desafío de mantener los formularios organizados y sin errores. Los formularios son complejos con muchos campos y su código puede resultar confuso y difícil de mantener.

¿Algo de eso te parece familiar?

Aquí es donde entra en juego React Hook Form . Esta biblioteca se encarga de todo el proceso de validación de formularios, permitiéndole crear formularios eficientes con menos código.

Es muy flexible, con validaciones basadas en restricciones que aprovechan el marcado HTML existente.

Es súper liviano y minimiza la cantidad de renderizaciones de páginas, lo que mejora el rendimiento de la página.

Entonces, en este artículo exploraremos cómo React Hook Form administra y valida los campos de nuestro formulario.

Aprenderás:

  • Diferencia entre componentes controlados y no controlados;
  • Cómo React Hook Form gestiona y valida los campos;
  • Validación de componentes personalizados;
  • Validación de componentes de bibliotecas de terceros.

Y mucho más. ¡Abróchate el cinturón y vámonos!

¿Cuál es la diferencia entre componentes controlados y no controlados?

Antes de trabajar con React Hook Form, es fundamental comprender la diferencia entre componentes controlados y no controlados, ya que la biblioteca tiene diferentes formas de tratar ambos tipos. Así que entendamos mejor a cada uno.

Componentes no controlados

En un componente no controlado , el estado lo mantiene el propio DOM, y no React.

Esto significa que en un formulario, React no conoce el estado de la entrada a menos que obtenga esa información utilizando otros recursos, por ejemplo useRef().

import React, { useRef } from 'react';
function Formulario() {
  const nombreRef = useRef();
  const emailRef = useRef();
  const handleSubmit = (e) => {
    e.preventDefault();
    // Accesando a los valores de los inputs diretamente por los elementos del formulário
    console.log(nombreRef.current.value);
    console.log(emailRef.current.value);
  };
  return (
    <form onSubmit={handleSubmit}>
      <input
        ref={nombreRef}
        name="nombre"
        type="text"
      />
      <input
        ref={emailRef}
        name="email"
        type="email"
      />
      <button type="submit">Enviar</button>
    </form>
  );
}

Este enfoque se acerca más a la forma en que normalmente funciona HTML, es decir, los valores de estos componentes se definen y se leen a través de atributos HTML, como value, checked (para checkboxes), selected (para select), etc.

import './App.css'
function App() {
  const onFormSubmit = (event) => {
    event.preventDefault()
    const form = event.target;
    const inputs = form.elements;
    const values = {};
    for (let i = 0; i < inputs.length; i++) {
      const input = inputs[i];
      if (input.name) {
        values[input.name] = input.value;
      }
    }
    console.log(values);
  }
  return (
    <>
      <form onSubmit={onFormSubmit}>
        <input type="text" name='nombre' placeholder='tu nombre'/>
        <input type="email" name='email' placeholder='tu email'/>
        <button type="submit">
          enviar
        </button>
      </form>
    </>
  )
}
export default App

Componentes controlados

Los componentes controlados tienen su estado totalmente controlado por React.

Esto significa que los valores de los campos se almacenan como parte del estado del componente.

Los valores de los campos del formulario se actualizan en respuesta a los cambios de estado de React. Imagino que alguna vez ya viste un componente controlado como este:

import React, { useState } from "react";
export const Form = () => {
  const [input, setInputValues] = useState({name: "", email:""});
const handleChange = (e) => {
    const { name, value } = e.target;
    setInputValues({ ...inputValues, [name]: value });
};
 function onSubmit(event) {
    event.preventDefault();
    console.log(input)
  }
  return (
    <form onSubmit={onSubmit}>
      <label>
        Name:
        <input
          type="text"
          onChange={(e) => handleChange(e)}
          value={input.name}
        />
      </label>
      <label>
        Email:
        <input
          type="email"
          onChange={(e) => handleChange(e)}
          value={input.email}
        />
      </label>
      <button type="submit">Enviar</button>
    </form>
  );
};

Los componentes controlados le brindan más control sobre los datos del formulario y son los más recomendados cuando se trabaja con formularios.

Si quieres ver ejemplos de componentes controlados en React, incluyendo checkboxes , select , radio botones y mucho más, te recomiendo leer el artículo de Jorge Nascimento sobre la plataforma Dev.to .

Sin embargo, ya sea que utilice componentes controlados o no controlados, sus formularios pueden resultar difíciles de mantener.

En momentos como este vale la pena conocer una forma de gestionarlos. Y ahí es donde entra en juego React Hook Form.

Forma de React Hook Form

Esta biblioteca se encarga de todo el proceso de validación de formularios, permitiéndo crear formularios eficientes, flexibles y de alto rendimiento, ya que elimina la representación innecesaria.

React Hook Form utiliza un enfoque de manos libres para administrar el estado de los campos del formulario, lo que significa menos código y mejor rendimiento.

Así, por ejemplo:

import React from 'react';
import { useForm } from 'react-hook-form';
function Form() {
  const { register, handleSubmit } = useForm();
  const onSubmit = data => {
    console.log(data);
  };
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("name")} placeholder="Nombre" />
      <input {...register("email")} placeholder="Email" />
      <button type="submit">Enviar</button>
    </form>
  );
}

Con React Hook Form, registra los campos de su formulario usando la función register, que esencialmente asocia un campo de entrada HTML con el estado interno de la biblioteca.

Esto permite que React Hook Form administre el estado del formulario, sin la necesidad de crear estados separados para cada campo.

Si desea comprender cómo register funciona, las funciones que devuelve y los props que acepta, le recomiendo leer la documentación del formulario React Hook haciendo clic en este enlace .

En el ejemplo anterior, usamos register para asociar los campos de entrada del formulario con el estado interno del formulario React Hook.

Esto nos permite acceder a los valores de los campos en el momento que se envía el formulario.

Quizás te preguntes: "¿Cómo?"

La magia está en el register. Cuando hacemos:

<input {...register("nombre")} placeholder="Nombre" />

Es lo mismo que hacerlo de esta forma:

const { onChange, onBlur, name, ref } = register('nome');
<input 
  onChange={onChange}
  onBlur={onBlur} 
  name={name}
  ref={ref}
  placeholder="Nome"
/>

El register devuelve algunas funciones importantes. El ref nos permite obtener los valores de este campo, y mediante la lógica interna podemos actualizar este valor con el onChange a través del formulario React Hook.

Componentes personalizados

En algunas situaciones, es posible que su aplicación ya tenga componentes desarrollados por ti (inputs, selects / dropdown, radio button, checkbox…) siguiendo los estándares de design de su equipo.

En casos como este, tiene más sentido integrarse con la biblioteca React Hook Form que desarrollar nuevos componentes desde cero. Veamos cómo implementar esto, usando el siguiente componente como ejemplo <Select>:

import { forwardRef } from 'react'
export interface IFormValues {
  name: string;
  age: number;
}
const Select = forwardRef<
  HTMLSelectElement,
  { label: string } & ReturnType<UseFormRegister<IFormValues>>
>(({ label }, ref) => (
    <div>
      <label>{label}</label>
      <select ref={ref} >
        <option value="20">20</option>
        <option value="30">30</option>
      </select>
    </div>
  )
);

En el componente Select, usamos forwardRef()para pasar ref directamente al select HTML.

Esto nos permite integrar fácilmente el componente con React Hook Form manteniendo la referencia al campo de edad ( age).

De forma predeterminada, los nodos del DOM de un componente son privados. Sin embargo, a veces es útil exponer un nodo del DOM a su componente principal, por ejemplo, para permitir que se pueda enfocar o, en este caso, para tener acceso a atributos como value, onchange, name, etc.

forwardRef permite que su componente exponga un nodo del DOM al componente principal con una referencia.

Si desea obtener más información sobre forwardRefy sus usos, te recomiendo leer la documentación de React haciendo clic en este enlace aquí .

También puedes usar register directamente dentro de tu componente, siempre que lo aceptes como prop.

Ten en cuenta que la propia biblioteca React Hook Form nos proporciona tipos para evitar escribir incorrectamente los props de nuestros componentes personalizados.

import { Path, UseFormRegister } from "react-hook-form"
import { IFormValues } from './'
type InputProps = {
  label: Path<IFormValues>
  register: UseFormRegister<IFormValues>
  required: boolean
}
const Input = ({ label, register, required }: InputProps) => (
  <>
    <label>{label}</label>
    <input {...register(label, { required })} />
  </>
)

En el ejemplo anterior, el componente <Input /> recibe props label, register y un required. El register se devuelve desde la biblioteca React Hook Form, mientras que lo requerido es un objeto que contiene las reglas de validación que el register puede recibir.

Podría utilizar estos componentes de la siguiente manera:

import { useForm, SubmitHandler } from "react-hook-form"
import { Input, Select } from './'
import IFormValues from './'
const App = () => {
  const { register, handleSubmit } = useForm<IFormValues>()
  const onSubmit: SubmitHandler<IFormValues> = (data) => {
    alert(JSON.stringify(data))
  }
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Input label="name" register={register} required />
      <Select label="age" {...register("age")} />
      <input type="submit" />
    </form>
  )
}

Quizás se pregunte: "¿Pero qué pasa con los casos en los que utilizamos componentes de interfaz de usuario de bibliotecas de terceros para crear la interfaz de nuestra aplicación?"

¡Es una excelente pregunta! Entendamos cómo trabajamos con este tipo de componentes.

Integración con bibliotecas de UI

Cuando utilizamos bibliotecas de componentes como MUI y Ant Design , podemos integrar React Hook Form sin ningún problema, incluso cuando estos componentes no aceptan directamente una referencia.

En este tipo de escenario, React Hook Form se encarga de todo el proceso de registro de nuestros componentes:

import { useForm, Controller, SubmitHandler } from "react-hook-form"
import { Input } from "@material-ui/core"
interface IFormInput {
  nombre: string
  contraseña: string
}
const App = () => {
  const { control, handleSubmit } = useForm<IFormInput>({
    defaultValues: {
      nombre: "",
      contraseña: ""
    },
  })
  const onSubmit: SubmitHandler<IFormInput> = (data) => {
    console.log(data)
  }
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Controller
        name="nombre"
        control={control}
        render={({ field }) => <Input {...field} />}
      />
      <Controller
        name="contraseña"
        control={control}
        render={({ field }) => <Input {...field} />}
      />
      <button type="submit">Enviar</button>
    </form>
  )
}

Dentro del formulario tenemos dos componentes Controller, uno para cada campo (nombre y contraseña).

Controller se utiliza para integrar campos de entrada de bibliotecas externas en react-hook-form.

Este componente recibe algunos props, incluyendo un name que sirve como identificador único para el campo, un render , que representa el componente externo que estamos usando y un control , que será responsable de controlar el componente externo.

Y así es como podemos integrar la biblioteca React Hook Form con componentes de bibliotecas de UI externas.

El componente Controller puede recibir otros accesorios, y si quieres profundizar en su uso te recomiendo leer la documentación disponible aquí en este enlace .

Conclusión

React Hook Form es una herramienta poderosa para simplificar la validación de formularios en React.

Al adoptar un enfoque no controlado y admitir componentes controlados a través del Controller , la herramienta le permite crear formularios eficientes con menos código y mejor rendimiento.

Si desea profundizar su conocimiento en React, le sugiero que realice nuestra capacitación de React .

Y hay cursos especifícos donde aprenderas más sobre hooks en React . Y nuestro Alura+ dónde aprenderás ¿qué son, y cómo funcionan?.

Espero verte allí! ¡Hasta la próxima!

Artículo adaptado y traducido por Daysibel Cotiz.

perfil-instructor

Neilton Seguins

Me gradué con una licenciatura en Ciencia y Tecnología e Ingeniería Mecánica. Trabajo como Instructor de desarrollo de software en Alura y tengo experiencia en desarrollo usando JavaScript/TypeScript, React js, Next js y Node.js. Me encanta compartir conocimientos, porque creo que la educación es transformadora y quiero cambiar la vida de las personas a través de la educación así como yo logré cambiar mi vida. También me encanta escuchar y tocar música, leer libros y manga y ver series.

Neilton Seguins
Neilton Seguins

Sou graduado como Bacharel em Ciência e Tecnologia e em Engenharia Mecânica. Atuo como Instrutor de Desenvolvedor de Software na Alura e possuo experiência com desenvolvimento usando JavaScript/TypeScript, React js, Next js e Node.js. Amo compartilhar conhecimento, pois acredito que a educação é transformadora e quero mudar a vida de pessoas através da educação assim como consegui mudar de vida. Também amo ouvir e tocar música, ler livros e mangás e assistir séries.

Artículo Anterior
Node.js para Frameworks Front-end
Siguiente Artículo
Componentes de React con TypeScript

Ver otros artículos sobre Front-end

Navegación

  • Planes
  • Instructores
  • Blog
  • Política de privacidad
  • Términos de uso
  • Sobre nosotros
  • Preguntas frecuentes

¡CONTÁCTANOS!

  • ¡Quiero entrar en contacto!

Blog

  • Programación
  • Data Science
  • Front End
  • Innovación y Gestión
  • DevOps

AOVS Sistemas de Informática S.A CNPJ 05.555.382/0001-33

SÍGUENOS EN NUESTRAS REDES SOCIALES

YouTube Facebook Instagram Linkedin Whatsapp Spotify

NOVEDADES Y LANZAMIENTOS

Aliados

  • Programa de aceleração Scale-Up Endeavor
  • En Alura somos unas de las Scale-Ups seleccionadas por Endeavor, programa de aceleración de las empresas que más crecen en el país.
  • Growth Academy 2021 do Google For Startups
  • Fuimos unas de las 7 startups seleccionadas por Google For Startups en participar del programa Growth Academy en 2021
Alura

Powered by

Caelum

AOVS Sistemas de Informática S.A CNPJ 05.555.382/0001-33

SÍGUENOS EN NUESTRAS REDES SOCIALES

YouTube Facebook Instagram Linkedin Whatsapp Spotify

Cursos

Cursos de Programación
Lógica de Programación | Java
Cursos de Front End
HTML y CSS | JavaScript | React
Cursos de Data Science
Data Science | Machine Learning | Excel | Base de Datos | Data Visualization | Estadística
Cursos de DevOps
Docker | Linux
Cursos de Innovación y Gestión
Transformación Ágil | Marketing Analytics

Alura

  • Educação em Tecnologia

    • logo fiap FIAP
    • logo casa do codigo Casa do Código
    • logo pm3 PM3 - Cursos de Produto
  • Mais Alura

    • logo alura start START BY Alura
    • logo alura lingua Alura Língua
    • logo alura para empresas Alura Para Empresas
    • logo alura latam Alura LATAM
  • Comunidade

    • logo tech guide Tech Guide
    • logo 7 days of code 7 days of code
    • logo Hipsters ponto Jobs Hipsters ponto Jobs
  • Podcasts

    • logo Hipster Network Hipster Network
    • logo Hipsters ponto Tech Hipsters ponto Tech
    • logo Dev sem fronteiras Dev sem Fronteiras
    • logo Like a Boss Like a Boss
    • logo IA Sob Controle IA Sob Controle
    • logo Mesa de Produto Mesa de Produto
    • logo Decode Decode
    • logo FIAPCast FIAPCast