Índice
- ¿Debería utilizar una biblioteca de formularios? #
- Factores a considerar #
- formik #
- Forma de gancho de reaccion #
- Forma definitiva #
Al manejar formularios en React, puede configurar una solución personalizada o comunicarse con una de las muchas bibliotecas de formularios disponibles. En este artículo, comparamos algunas bibliotecas de React, Formik, React Hook Form, React Final Form y Unform.
Trabajar con las aportaciones de los usuarios siempre ha sido una de las partes más importantes del desarrollo de cualquier sitio web. Manejar cosas como la validación, el envío y la visualización de errores de formularios puede volverse complejo, por lo que usar las soluciones de formularios existentes puede ser el camino a seguir, y existen varias soluciones para manejar formularios en React.
En este artículo, veremos Formik , React Hook Form , React Final Form y Unform . Compararemos cómo se usan, cómo podemos integrarlos en componentes de interfaz de usuario personalizados y cómo configurar campos dependientes con ellos. En el camino, también aprenderemos cómo validar formularios usando Yup , un validador de esquemas de objetos JavaScript.
Este artículo es útil para aquellos que desean conocer las mejores bibliotecas de formularios para usar en aplicaciones futuras.
Nota: este artículo requiere una comprensión básica de React y Yup.
¿Debería utilizar una biblioteca de formularios? #
Los formularios son una parte integral de cómo los usuarios interactúan con la web. Se utilizan para recopilar datos de los usuarios para su procesamiento y, hoy en día, muchos sitios web tienen uno o más formularios. Si bien los formularios se pueden manejar en React convirtiéndolos en componentes controlados , puede resultar tedioso con una gran cantidad de código repetitivo si se crean muchos formularios. Tiene la opción de comunicarse con una de las muchas bibliotecas de formularios que existen en el ecosistema React. Estas bibliotecas facilitan la creación de formularios de diversa complejidad, ya que proporcionan validación y administración de estado listas para usar, entre otras funciones útiles de manejo de formularios.
Factores a considerar #
Una cosa es conocer las diferentes bibliotecas de formularios disponibles y otra saber cuál es la adecuada para usar en su próximo proyecto. En este artículo, examinaremos cómo funcionan estas bibliotecas de formularios y las compararemos en función de los siguientes factores:
- Implementación
Analizaremos sus API y consideraremos qué tan fácil es integrarlas en una aplicación, manejar la validación y el envío de formularios y la experiencia general del desarrollador. - Uso con componentes personalizados
¿Qué tan fácil es integrar estas bibliotecas con entradas de bibliotecas de UI como Material UI? - Campos dependientes
Es posible que desee representar un campo de formulario B que dependa del valor de un campo A. ¿Cómo podemos manejar ese caso de uso con estas bibliotecas? - Curva de aprendizaje
¿Qué tan rápido puede comenzar a utilizar estos formularios? ¿Cuántos recursos de aprendizaje y ejemplos hay disponibles en línea? - Tamaño del paquete
Siempre queremos que nuestras aplicaciones tengan buen rendimiento. ¿Qué ventajas y desventajas existen en términos del tamaño del paquete de estas formas?
También consideraremos cómo crear formularios de varios pasos usando estas bibliotecas. No agregué eso a la lista anterior debido a cómo estructuré el artículo. Lo veremos al final del artículo.
formik #
Formik es una biblioteca flexible. Puede optar por utilizar Formik con elementos HTML nativos o con componentes personalizados de Formik. También tiene la opción de configurar sus reglas de validación de formularios o una solución de terceros como Sí. Te permite decidir cuándo y cuánto quieres usarlo. Podemos controlar cuánta funcionalidad de la biblioteca Formik utilizamos.
Formik se encarga de las cosas repetitivas y molestas (realizar un seguimiento de los valores, errores, campos visitados, orquestar la validación y gestionar el envío) para que usted no tenga que hacerlo. Esto significa que dedica menos tiempo a configurar el estado del formulario y onChange
los onBlur
controladores.
Instalación #
npm i formikyarn add formik
Implementación #
Formik realiza un seguimiento del estado de su formulario y luego lo expone junto con algunos métodos reutilizables y controladores de eventos ( handleChange
, handleBlur
y handleSubmit
) a su formulario a través de props
. Puede obtener más información sobre los métodos disponibles en Formik aquí .
Si bien Formik se puede usar junto con los campos de entrada nativos de HTML, Formik viene con un Field
componente que puede usar para determinar el campo de entrada que desea y un ErrorMessage
componente que se encarga de mostrar el error para cada campo de entrada. Veamos cómo funcionan en la práctica.
import { Form, Field, ErrorMessage, withFormik } from "formik";const App = ({ values }) = ( div className={styles.container} Head titleFormik Form/title /Head Form div className={styles.formRow} label htmlFor="email"Email/label Field type="email" name="email" id="email" / ErrorMessage name="email" component="span" className={styles.error} / /div div className={styles.formRow} label htmlFor="email"Select a color to continue/label Field component="select" name="select" option value="" label="Select a color" / option value="red" label="red" / option value="blue" label="blue" / option value="green" label="green" / /Field ErrorMessage name="select" component="span" className={styles.error} / /div div className={styles.formRow} label htmlFor="checkbox" Field type="checkbox" name="checkbox" checked={values.checkbox} / Accept Terms Conditions /label ErrorMessage name="checkbox" component="span" className={styles.error} / /div div role="group" aria-labelledby="my-radio-group" label Field type="radio" name="radio" value="Option 1" / One /label label Field type="radio" name="radio" value="Option 2" / Two /label ErrorMessage name="radio" component="span" className={styles.error} / /div button type="submit" className={"disabled-btn"} Sign In /button /Form /div);
En el código anterior, estamos trabajando con cuatro campos de entrada, un correo electrónico, una selección, una casilla de verificación y un campo de radio. Form
es un pequeño contenedor alrededor de un form
elemento HTML que se conecta automáticamente a Formik handleSubmit
y handleReset
. Analizaremos qué withFormik
sucederá a continuación.
import { Form, Field, ErrorMessage, withFormik } from "formik";import * as Yup from "yup";const App = ({ values }) = ( div className={styles.container} Head titleFormik Form/title /Head Form //form stuffs here button type="submit" className={"disabled-btn"} Sign In /button /Form /div);const FormikApp = withFormik({ mapPropsToValues: ({ email, select, checkbox, radio }) = { return { email: email || "", select: select || "", checkbox: checkbox || false, radio: radio || "", }; }, validationSchema: Yup.object().shape({ select: Yup.string().required("Color is required!"), email: Yup.string().email().required("Email is required"), checkbox: Yup.bool().oneOf([true], "Checkbox is required"), radio: Yup.string().required("Radio is required!"), }), handleSubmit: (values) = { alert(JSON.stringify(values)); },})(App);export default FormikApp;
withFormik
es un HOC que inyecta contexto Formik dentro del componente empaquetado. Podemos pasar un options
objeto withFormik
donde definimos el comportamiento del contexto de Formik.
Formik funciona bien con Yup en el manejo de la validación del formulario, por lo que no tenemos que configurar reglas de validación personalizadas. Definimos un esquema para la validación y se lo pasamos a validationSchema
. Con mapPropsToValues
, Formik transfiere el estado actualizado de los campos de entrada y pone los valores a disposición del App
componente a través de accesorios como props.values
. La handleSubmit
función maneja el envío del formulario.
Uso con componentes personalizados #
Otro beneficio de Formik es lo sencillo que es integrar bibliotecas de UI personalizadas y sus componentes de formulario. Aquí, configuramos un formulario básico usando TextField
el componente Material UI.
import TextField from "@material-ui/core/TextField";import * as Yup from "yup";import { Formik, Form, Field, ErrorMessage } from "formik";const signInSchema = Yup.object().shape({ email: Yup.string().email().required("Email is required"),});export default function SignIn() { const classes = useStyles(); return ( Container component="main" maxWidth="xs" div className={classes.paper} Formik initialValues={initialValues} validationSchema={SignInSchema} onSubmit={(values) = { alert(JSON.stringify(values)); }} {({ errors, values, handleChange, handleBlur, handleSubmit, touched, }) = ( Form className={classes.form} onSubmit={handleSubmit} Field as={TextField} variant="outlined" margin="normal" fullWidth id="email" label="Email Address" name="email" helperText={ErrorMessage name="email" /} / button type="submit"submit/button /Form )} /Formik /div /Container );}
Field
conecta las entradas a Formik automáticamente. Formik inyecta onChange
, onBlur
, name
y value
accesorios al TextField
componente. Hace lo mismo con cualquier tipo de componente personalizado que decida utilizar. Pasamos TextField
por Field
su as
puntal.
También podemos usar TextField
el componente de Material UI directamente. Los documentos también proporcionan un ejemplo que cubre ese escenario.
Campos dependientes #
Para configurar campos dependientes en Formik, accedemos al valor de entrada que queremos rastrear a través del values
objeto en los accesorios de renderizado. Aquí, rastreamos el remember
campo, que es la casilla de verificación, y presentamos un mensaje según el estado del campo.
Field name="remember" type="checkbox" as={Checkbox} Label={{ label: "You must accept our terms!!!" }} helperText={ErrorMessage name="remember" /} / {values.remember ( p Thank you for accepting our terms. You can now submit the form /p)}
Curva de aprendizaje #
Los documentos de Formik son fáciles de entender y van directos al grano. Cubre varios casos de uso, incluido cómo usar Formik con bibliotecas de UI de terceros como Material UI. También hay varios recursos de la comunidad Formik para ayudarle en su aprendizaje.
Tamaño del paquete #
Formik tiene un tamaño de 44,4 kb minificado y 13,1 kb comprimidos con gzip.
- Aproveche la sólida recuperación de datos y el tamaño de paquete optimizado con KendoReact Server Data Grid Probar ahora
Forma de gancho de reaccion #
React Hook Form , o RHF, es una biblioteca de formularios ligera, flexible y sin dependencia creada para React.
Instalación #
npm i react-hook-formyarn add react-hook-form
Implementación #
RHF proporciona un useForm
gancho que podemos utilizar para trabajar con formularios.
Comenzamos configurando los campos de entrada HTML que necesitamos para este formulario. A diferencia de Formik, RHF no tiene un Field
componente personalizado, por lo que usaremos los campos de entrada nativos de HTML.
import { useForm } from "react-hook-form";const validationSchema = Yup.object().shape({ select: Yup.string().required("Color is required!"), email: Yup.string().email().required("Email is required"), checkbox: Yup.bool().oneOf([true], "Checkbox is required"), radio: Yup.string().required("Radio is required!"),});const onSubmit = (values) = { alert(JSON.stringify(values));};const App = () = { const { errors, register, handleSubmit } = useForm({ resolver: yupResolver(validationSchema), }); return ( div className="container" form onSubmit={handleSubmit(onSubmit)} //email field div className="form-row" label htmlFor="email"Email/label input type="email" name="email" id="email" ref={register} / {errors.email p className="error" {errors.email.message} /p} /div //select field div className="form-row" label htmlFor="email"Select a color to continue/label select name="select" ref={register} option value="" label="Select a color" / option value="red" label="red" / option value="blue" label="blue" / option value="green" label="green" / /select {errors.select p className="error" {errors.select.message} /p} /div //checkbox field div className="form-row" label htmlFor="checkbox" input type="checkbox" name="checkbox" ref={register} / Accept Terms Conditions /label {errors.checkbox ( p className="error" {errors.checkbox.message} /p )} /div //radio field div label input type="radio" name="radio" value="Option 1" ref={register} / One /label label input type="radio" name="radio" value="Option 2" ref={register} / Two /label {errors.radio p className="error" {errors.radio.message} /p} /div button type="submit"Sign In/button /form /div );};
RHF admite Yup y otros esquemas de validación . Para usar Yup con RHF, necesitamos instalar el @hookform/resolvers
paquete. Juguetes educativos
npm i @hookform/resolvers
Next, we have to configure the RHF setup and instruct it to use Yup as the form validator. We do so through the resolver
property useForm
hook’s configuration. object. We pass in yupResolver
, and now RHF knows to use Yup to validate the form.
The useForm
hook gives us access to several form methods and properties like an errors
object, and the handleSubmit
and register
methods. There are other methods we can extract from useForm
. You can find the complete list of methods.
The register
function connects input fields to RHF through the input field’s ref
prop. We pass the register
function as a ref
into each element we want RHF to watch. This approach makes the forms more performant and avoids unnecessary re-renders.
The handleSubmit
method handles the form submission. It will only run if there are no errors in the form.
The errors
object contains the errors present in each field.
Uso con componentes personalizados
RHF has made it easy to integrate with external UI component libraries. When using custom components, check if the component you wish to use exposes a ref
. If it does, you can use it like you would native HTML form elements. However, if it doesn’t you will need to use RHF’s Controller
component.
Material-UI and Reactstrap’s TextField
expose their inputRef
, so you can pass register
to it.
import TextField from "@material-ui/core/TextField";export default function SignIn() { return ( Container component="main" maxWidth="xs" div className={classes.paper} form className={classes.form} TextField inputRef={register} id="email" label="Email Address" name="email" error={!!errors.email} helperText={errors?.email?.message} / Button type="submit"Sign In/Button /form /div /Container );}
In a situation where the custom component’s inputRef
is not exposed, we have to use RHF’s Controller
component.
import { useForm, Controller } from "react-hook-form";import FormControlLabel from "@material-ui/core/FormControlLabel";import Checkbox from "@material-ui/core/Checkbox";export default function SignIn() { const { control } = useForm() return ( Container component="main" maxWidth="xs" div className={classes.paper} form FormControlLabel control={ Controller control={control} name="remember" color="primary" render={(props) = ( Checkbox checked={props.value} onChange={(e) = props.onChange(e.target.checked)} / )} / } label="Remember me" / Button type="submit" Sign In /Button /form /div /Container );}
We import the Controller
component from RHF and access the control
object from the useForm
hook.
Controller
acts as a wrapper that allows us to use custom components in RHF. Any prop passed into Controller
will be propagated down to the Checkbox
.
The render
prop function returns a React element and provides the ability to attach events and value into the component. This simplifies integrating RHF with custom components. render
provides onChange
, onBlur
, name
, ref
, and value
to the custom component.
Campos dependientes #
In some situations, you may want to render a secondary form field based on the value a user puts in field a primary form field. RHF provides a watch
API that enables us to track the value of am input field.
export default function SignIn() { const { watch } = useForm() const terms = watch("remember"); return ( Container component="main" maxWidth="xs" div className={classes.paper} form //other fields above {terms pThank you for accepting our terms. You can now submit the form/p} Button type="submit" Sign In /Button /form /div /Container );}
Curva de aprendizaje #
Asides from its extensive and straightforward documentation that covers several use cases, RHF is a very popular React Library. This means there are several learning resources to get you up and running.
Tamaño del paquete #
RHF is 26.4kb minified and 9.1kb gzipped.
Forma definitiva #
Final Form is a framework-agnostic form library. However, its creator, Erik Rasmussen, created a React wrapper for Final Form, React Final Form.
Instalación #
npm i final-form react-final-formyarn add final-form react-final-form
Implementación #
Unlike Formik and React Hook Form, React Final Form (RFF) does not support validation with Object Schemas like Yup out of the box. This means you have to set up validation yourself.
import { Form, Field } from "react-final-form";export default function App() { return ( div className={styles.container} Head titleReact Final Form/title /Head Form onSubmit={onSubmit} validate={validate} render={({ handleSubmit }) = ( form onSubmit={handleSubmit} //email field Field name="email" {({ input, meta }) = ( div className={styles.formRow} labelEmail/label input {...input} type="email" placeholder="Email" / /div )} /Field //select field Field name="select" component="select" {({ input, meta }) = ( div className={styles.formRow} label htmlFor="select"Select a color to continue/label select {...input} option value="" label="Select a color" / option value="red" label="red" / option value="blue" label="blue" / option value="green" label="green" / /select /div )} /Field //checkbox field Field name="checkbox" {({ input, meta }) = ( div className={styles.formRow} label input {...input} name="checkbox" type="checkbox" / Accept Terms Conditions /label /div )} /Field //radio field div className={styles.formRow}2 Field name="radio" component="input" type="radio" value="Option 1" {({ input, meta }) = ( div label One input {...input} type="radio" value="Option 1" / /label /div )} /Field Field name="radio" component="input" type="radio" value="Option 2" {({ input, meta }) = ( div label Two input {...input} type="radio" value="Option 2" / /label /div )} /Field /div button type="submit" className={"disabled-btn"} Sign In /button /form )} / /div );}
The Form
component is a special wrapper provided by RFF that manages the state of the form. The main props
when using RFF are onSubmit
, validate
, and render
. You can get more details on the form props RFF works with.
We start by setting up the necessary input fields. render
handles the rendering of the form. Through the render props, we have access to the FormState
object. It contains form methods like handleSubmit
, and other useful properties regarding the state of the form.
Like Formik, RFF has its own Field
component for rendering input fields. The Field
component registers any input field in it, subscribes to the input field’s state, and injects both field state and callback functions, onBlur
, onChange
, and onFocus
via a render prop.
Unlike Formik and RHF, RFF does not provide support for any validation Schema, so we have to set up custom validation rules.
const onSubmit = (values) = { alert(JSON.stringify(values));};const validate = (values) = { const errors = {}; if (!values.email) { errors.email = "Email is Required"; } else if (!/^[^s@]+@[^s@]+.[^s@]+$/.test(values.email)) { errors.email = "Invalid emaill address"; } if (!values.checkbox) { errors.checkbox = "You must accept our terms"; } if (!values.select) { errors.select = "Select is required"; } if (!values.radio) { errors.radio = "You must accept our terms"; } return errors;};export default function App() { return ( div className={styles.container} Form onSubmit={onSubmit} validate={validate} render={({ handleSubmit }) = ( form onSubmit={handleSubmit} Field name="email" {({ input, meta }) = ( div className={styles.formRow} labelEmail/label input {...input} type="email" placeholder="Email" / {meta.error meta.touched ( span className={styles.error}{meta.error}/span )} /div )} /Field Field name="select" component="select" {({ input, meta }) = ( div className={styles.formRow} label htmlFor="select"Select a color to continue/label select {...input} option value="" label="Select a color" / option value="red" label="red" / option value="blue" label="blue" / option value="green" label="green" / /select {meta.error meta.touched ( span className={styles.error} style={{ display: "block" }} {meta.error} /span )} /div )} /Field Field name="checkbox" {({ input, meta }) = ( div className={styles.formRow} label input {...input} name="checkbox" type="checkbox" / Accept Terms Conditions /label {meta.error meta.touched ( span className={styles.error}{meta.error}/span )} /div )} /Field div className={styles.formRow} Field name="radio" component="input" type="radio" value="Option 1" {({ input, meta }) = ( div label One input {...input} type="radio" value="Option 1" / /label /div )} /Field Field name="radio" component="input" type="radio" value="Option 2" {({ input, meta }) = ( div label Two input {...input} type="radio" value="Option 2" / /label {meta.error meta.touched ( span className={styles.error}{meta.error}/span )} /div )} /Field /div button type="submit" className={"disabled-btn"} Sign In /button /form )} / /div );}
The validate
function handles the validation for the form. The onSubmit
function will be called with the values of your form when the user submits the form and all validation passes. Validation runs on input change by default. However, we can also pass a validateonBlur
prop to the Form
component validation so it also runs on blur.
To display the validation errors, we make use of the meta
object. We can get access to the metadata and state of each input field through the meta
object. We can find out if the form has been touched or has any errors through the meta
’s touched
and error
properties respectively. These metadata are part of the props of the Field
component. If the input fields have been touched, and there is an error for we display that error.
Uso con componentes personalizados
Working with custom input components in RFF is straightforward. Using the render props method in the Field
component, we can access the input
and meta
of each input field.
const onSubmit = (values) = {...};const validate = (values) = {...};export default function App() { return ( Form onSubmit={onSubmit} validate={validate} render={({ handleSubmit }) = ( form onSubmit={handleS
Tal vez te puede interesar:
- 40 bibliotecas útiles de JavaScript
- Bibliotecas prácticas de JavaScript y complementos de jQuery
- Bibliotecas de JavaScript útiles y complementos de jQuery: parte 2
- Bibliotecas JavaScript útiles y complementos jQuery
Comparación de cuatro bibliotecas de formularios de React: Formik, React Hook Form, React Final Form y Unform
¿Debería utilizar una biblioteca de formularios? #Factores a considerar #formik #Forma de gancho de reaccion #Forma definitiva #Tal vez te puede interesar:Cl
programar
es
https://aprendeprogramando.es/static/images/programar-comparacion-de-cuatro-bibliotecas-de-formularios-de-react-formik-1164-0.jpg
2025-01-08
Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente