27

Buenas y malas prácticas para crear formularios en React

49138Puntos

hace un año

Al trabajar con formularios en React es común caer en malas prácticas, como declarar estados y event handlers separados por cada input. Afortunadamente, React nos ofrece alternativas para escribir formularios mucho más limpios, reutilizando código y asegurándonos de recibir exactamente la información que necesitamos.

Malas prácticas con formularios en React

Una de las acciones que hacemos continuamente una vez empezamos con este framework es el tratar de usar el estado y ciclo de vida para todo lo que veamos, lo cual produce que nuestro código no se vea tan limpio.

import React, { useState } from "react";

const MyNiceForm = () => {
	// Declarar un estado por cada input ❌const [username, setUsername] = useState();
  const [email, setEmail] = useState();
  const [password, setPassword] = useState();

	const sendData = (user, mail, pass) => {
    console.log(user, mail, pass)
  }

  const handleSubmit = (e) => {
    e.preventDefault()
    sendData(username, email, password)
  }

  // Declarar un evento onChange para que cada input capture el valor ❌return(
    <form onSubmit={handleSubmit}>
			<input
        onChange={(e) => setEmail(e.target.value)}
				required
        type="email"
				name="email"
				placeholder="Email"/>
			<input
        required
        onChange={(e) => setUsername(e.target.value)}
				type="text"
				name="username"
				placeholder="Username"/>
			<input
        required
        onChange={(e) => setPassword(e.target.value)}
				type="password"
				name="password"
				placeholder="Password"/>
			<button type="submit">
				Submit data
			</button>
		</form>
	)
}

👀 Un pequeño paréntesis: esto suele ser una mala práctica para formularios : convencionales", pero si tu aplicación necesita mostrarle al usuario un mensaje que cambie en tiempo real con los datos que está introduciendo, un código similar al de arriba funciona bien.

Buenas prácticas con formularios en React

Para corregir esto tenemos varias opciones. Una de ellas es delegar el trabajo al evento onSubmit.

Nos vamos a olvidar completamente de useState para explotar al máximo las características que ya traen de forma nativa los forms de HTML; acceder directamente desde el form a todos los inputs que están dentro.

const MyFancyForm = () => {
	// sendData va a simular ser solo una función que hace algo con la data
  const sendData = (user, mail, pass) => {
    console.log(user, mail, pass)
  }

  // Vamos a capturar el evento y vamos a prevenir que siga el comportamiento// por defecto para que podamos manipular la data correctamente// Desde el evento que capturamos("e"), podemos acceder a los valores de los// inputs con los nombres que definimos (email, username, password)
  return(
    <form onSubmit={(e) => {
        e.preventDefault()
        sendData(
         e.target.email.value,
         e.target.username.value,
         e.target.password.value
        )
      }}>

	    <input 
					required 
					type="email" 
					name="email" 
					placeholder="Email" 
				/>
			<input 
				required 
				type="text"
				name="username" 
				placeholder="Username" 
			/>
			<input 
				required 
				type="password" 
				name="password" 
				placeholder="Password"
			/>
			<button type="submit">
				Submit data
			</button>
		</form>
	)
}

Poniendo en práctica el FormData

Dentro del navegador ya tenemos algunas ayudas para que nuestros forms sean mucho más fáciles de hacer. FormData es una clase proveniente de nuestro browser, no tendremos que instalar ninguna dependencia adicional, solo crear una instancia y empezar con la magia.

Va a ser similar al caso anterior, solo que ahora utilizaremos un React hook de apoyo, ya que debemos indicar qué nodo hace parte del form. Esta tarea nos la facilitará useRef.

import React, { useRef } from 'react'const MyFancyForm = () => {
	// Inicializamos nuestra referenciaconst form = useRef(null)

  // sendData se mantendrá como nuestra función que simula mandar dataconst sendData = (user, mail, pass) => {
      console.log(user, mail, pass)
  }

	// Nuestro handleSubmit hace toda la magiaconst handleSubmit = () => {
    // Instanciamos a la clase FormData con el nodo de form para acceder// a los valores de los inputconst formData = new FormData(form.current);
		// Creamos un objeto que va a guardar los valores// Que a su vez obtenemos mediante el FormDataconst user = {
      'username': formData.get('username'),
      'email': formData.get('email'),
      'password': formData.get('password'),
    }
		// Aquí es donde simulamos mandar nuestra data
   sendData(user.username, user.email, user.password)
  }

  // Es importante que nuestra referencia este dentro el nodo de form// Para así poder acceder a los valores con el handleSubmitreturn(
    <form ref={form}>
			<input 
				required 
				type="email" 
				name="email" 
				placeholder="Email" 
			/>
			<input
        required
        type="text"
				name="username"
				placeholder="Username"/>
			<input
        required
        type="password"
				name="password"
				placeholder="Password"
			/>
      <button type="button" onClick={handleSubmit}>
				Submit data
			</button>
		</form>
	)
}

Manejar así la información nos permite tener un mayor control de la data (pudiendo agregarla a un contexto, por ejemplo).

Solo hay un pequeño problema: las validaciones no parecen funcionar, por lo que deberás hacer validaciones con JavaScript, donde igual deberemos tener cuidado de no escribir código repetitivo por cada input que tengamos.

React Hook Form

Al ser un problema tan común en el desarrollo de las aplicaciones web, a alguien se le ocurrió facilitar todo esto con una sola herramienta. Su uso es muy sencillo, solo debes instalarla como cualquier otra dependencia:

  • npm install react-hook-form
  • yarn add react-hook-form

Solo basta con importar el hook de useForm y usar sus utilidades como lo son:

  • register: esta funcionalidad nos ayudará a guardar en un objeto toda la data de una manera más sencilla, para usarlo debemos insertarlo en cada input ({...register(value-name)})
  • handleSubmit: con handleSubmit tendremos a toda la data que fue recabada con register, esta se le pasa al evento onSubmit de los forms y dentro de ella otra función que nos permita acceder a la data, para usarlo debes hacerlo de la siguiente forma:
<formonSubmit={handleSubmit(myFunc)} >...
</form>
  • watch: viene a suplir a lo que conocemos con el evento onChange, podemos hacer uso de esta función en cualquier parte de nuestro código, solo debemos pasarle el atributo name que usamos en el register
  • formState: con formState podremos acceder al estado de nuestro formulario para saber si tuvo éxito o no.
import React from 'react';
import { useForm } from 'react-hook-form';

const MyFancyForm = () => {
	const { register, handleSubmit } = useForm()
  const sendData = (data) => {
    console.log(data.username, data.email, data.password)
  }

  // Una característica de register es que desde ahí podemos definir// si un atributo es requrido o noreturn(
    <form onSubmit={handleSubmit(sendData)}>
			<input
	     {...register("email", { required: true })}
			 type="email"
			 placeholder="Email"/>
			<input
        {...register("username", { required: true })}
				type="text"
				placeholder="Username"/>
			<input
        {...register("password", { required: true })}
				type="password"
				placeholder="Password"
			/>
			<button type="submit">
				Submit data
			</button>
		</form>
	)
}

Aunque parezca que volvamos a adoptar la mala práctica de repetir código, con este hook podrás hacer que tus inputs sean más rigurosos, ya que podrás definir el mínimo, máximo, verificar por qué falló, tener mensajes más descriptivos, entre muchas otras características que trae esta librería para ayudarte.

Cómo diferenciar buenas prácticas de malas prácticas

Una vez empiezas a emplear estas prácticas y herramientas en tus proyectos podrás darte cuenta de lo siguiente:

  • Podrás tener forms con muchos más campos.
  • Evitas el código repetitivo (DRY).
  • Tu código se ve más limpio.
  • Mantener este código es mucho más sencillo.

Como dev vas a estar constantemente cambiando piezas de código en diferentes partes de tus proyectos. Tener un código bien cuidado y fácil de reemplazar te va a ahorrar horas de trabajo y dolores de cabeza. Por eso te quiero recomendar una serie de cursos para que aprendas de los mejores a escribir un mejor código en React:

Leonardo de los angeles
Leonardo de los angeles
LeoCode0

49138Puntos

hace un año

Todas sus entradas
Escribe tu comentario
+ 2