Cómo crear formularios con la biblioteca Formik en React

Explicamos cómo funciona la biblioteca Formik para crear formularios en React y por qué la recomendamos
Este artículo es más adecuado para aquellos que ya tienen un conocimiento básico de JS. Si aún no lo has dominado, te recomendamos que antes de leerlo realices el curso de JavaScript en Códica.
¿Qué es Formik?
Formik es una biblioteca comprensible, gratuita y de código abierto para React o React Native que resuelve tres tareas principales al crear formularios:
  • Gestión del estado del formulario
  • Validación del formulario
  • Envío del formulario
La biblioteca Formik fue escrita por Jared Palmer, director de herramientas y plataformas para desarrolladores de Vercel, durante la creación de un gran panel de administración interno. El objetivo principal era estandarizar no solo todos los formularios, sino también cómo los datos pasaban a través de ellos, lo que simplificaría en gran medida las pruebas, refactorizaciones y análisis de estos formularios.
¿Qué es Formik?
Crear un formulario solo con React requiere que el desarrollador escriba cada parte del proceso por sí mismo, desde la configuración del estado hasta el envío del formulario. El programador debe tener en cuenta que:
  • Es necesario almacenar y rastrear los valores de los campos del formulario, los errores y el estado de validación de cada campo
  • Se debe manejar la entrada del usuario y cambiar el estado del formulario
  • Es necesario pensar y describir las validaciones por sí mismo
  • Se debe describir el proceso de envío del formulario
Formik se encarga de todas estas preocupaciones y proporciona una serie de componentes y hooks para crear formularios en React y React Native. A continuación, en el artículo, nos familiarizaremos con los componentes principales de esta biblioteca: <Formik />, <Form />, <Field /> y <ErrorMessage />.
Cómo gestionar el estado del formulario en Formik
Para comenzar a trabajar con Formik, simplemente envuelve el formulario en el componente <Formik />:

<Formik>
  <Form>
    {/* aquí va el resto del código */}
  </Form>
</Formik>
Con la propiedad initialValues, inicializamos el estado inicial del formulario dentro de Formik. Además, para obtener y actualizar el estado de los campos del formulario, podemos usar el componente <Field /> en lugar del elemento HTML <input />. Este componente sincronizará automáticamente el estado y no necesitaremos pasar las propiedades value y onChange a través de los props:

<Formik
  initialValues={{ email: "", password: "" }}
  onSubmit={({ setSubmitting }) => {
    console.log("Form is validated! Submitting the form...");
    setSubmitting(false);
  }}
>
  {() => (
    <Form>
      <div className="form-group">
        <label htmlFor="email">Email</label>
        <Field
          type="email"
          name="email"
          className="form-control"
        />
      </div>
      <div className="form-group">
        <label htmlFor="password">Password</label>
        <Field
          type="password"
          name="password"
          className="form-control"
        />
      </div>
    </Form>
  )}
</Formik>
Formik tiene su propio método handleChange, que se puede utilizar para actualizar el estado cuando el usuario introduce datos en los campos del formulario. De esta manera, no es necesario implementar nuestro propio método handleChange. En el siguiente ejemplo, el método handleChange actualiza los valores del campo email en el estado del formulario en función del atributo name, si hay cambios en este campo:

const SignupForm = () => {
  const formik = useFormik({
    initialValues: {
      email: "",
    },
    onSubmit: (values) => {
      console.log(JSON.stringify(values, null, 2));
    },
  });
  return (
    <form onSubmit={formik.handleSubmit}>
      <label htmlFor="email">Email Address</label>
      <input
        id="email"
        name="email"
        type="email"
        onChange={formik.handleChange}
        value={formik.values.email}
      />

      <button type="submit">Submit</button>
    </form>
  );
};
El método handleChange se utiliza con elementos de entrada (input), mientras que el componente <Field> actualiza automáticamente los valores sin necesidad de implementar el método handleChange.
Validación y mensajes de error en Formik
La validación es muy importante al crear formularios. Si los formularios no se manejan correctamente, pueden producirse muchos errores. Los formularios deben informar a los usuarios qué campos son obligatorios y qué tipos de valores están permitidos en campos específicos. Esto también ayuda a dar a los usuarios una comprensión clara de lo que está mal con su entrada.

La validación en Formik se realiza automáticamente durante eventos específicos, como la entrada de datos del usuario, el cambio de enfoque y el envío. Formik admite tanto la validación a nivel de formulario como a nivel de campo. Todo lo que tienes que hacer es pasar una función de validación al componente <Formik /> o <Field /> a través de la propiedad validate:

// Synchronous validation
 const validate = (values, props) => {
   const errors = {};
 
   if (!values.email) {
     errors.email = 'Required';
   } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
     errors.email = 'Invalid email address';
   }
 
   //...
 
   return errors;
 };
Cómo mostrar mensajes de error en Formik
Formik proporciona el componente <ErrorMessage /> para mostrar automáticamente mensajes de error para el componente <Field /> con el nombre correspondiente (name).

<ErrorMessage /> permite especificar qué etiqueta HTML se mostrará a través de la propiedad component:

<Field
  type="email"
  name="email"
  className={`form-control ${
    touched.email && errors.email ? "is-invalid" : ""
  }`}
/>
<ErrorMessage
  component="div"
  name="email"
  className="invalid-feedback"
/>
Validación con Yup
Como mencionamos anteriormente, Formik admite tanto la validación a nivel de formulario como a nivel de campo, y el desarrollador tiene la opción de escribir su propia implementación de validación. Sin embargo, también puedes ir un paso más allá y utilizar la integración de Formik con Yup.

Yup es una biblioteca de validación de objetos JS. Permite describir un esquema de validación para un objeto, donde se establecen una serie de restricciones para cada propiedad del objeto, y luego se llama al método de validación validate en ese objeto.

Formik proporciona soporte para esquemas de validación validationSchema en Yup, que automáticamente convierte los errores de validación de Yup en un objeto cuyas claves corresponden a los valores de los campos del formulario.
También te puede interesar:

Cómo implementar una aplicación en Railway. Guía para desarrolladores frontend y backend
Para agregar Yup a tu proyecto, debes instalarlo desde npm:

npm install yup --save

import React from 'react';
import { Formik, Form, Field } from 'formik';
import * as Yup from 'yup';

const SignupSchema = Yup.object().shape({
  firstName: Yup.string()
    .min(2, 'Mínimo 2 letras')
    .max(50, 'Máximo 50 letras')
    .required('Campo obligatorio'),
  lastName: Yup.string()
    .min(2, 'Mínimo 2 letras')
    .max(50, 'Máximo 50 letras')
    .required('Campo obligatorio'),
  email: Yup.string().email('Email no válido').required('Campo obligatorio'),
});

export const ValidationSchemaExample = () => (
  <div>
    <h1>Registro</h1>
    <Formik
      initialValues={{
        firstName: '',
        lastName: '',
        email: '',
      }}
      validationSchema={SignupSchema}
      onSubmit={ (values) => {
        console.log(values);
      }}
    >
      {({ errors, touched }) => (
        <Form>
          <Field name="firstName" />
          {errors.firstName && touched.firstName ? (
            <div>{errors.firstName}</div>
          ) : null}
          <Field name="lastName" />
          {errors.lastName && touched.lastName ? (
            <div>{errors.lastName}</div>
          ) : null}
          <Field name="email" type="email" />
          {errors.email && touched.email ? <div>{errors.email}</div> : null}
          <button type="submit">Submit</button>
        </Form>
      )}
    </Formik>
  </div>
);
Envío de formularios en Formik
Formik utiliza la función onSubmit para manejar los datos del formulario cada vez que se presiona el botón de envío. La validación se ejecuta automáticamente, pero el envío del formulario se cancelará si hay algún error.

En el siguiente ejemplo, la función onSubmit se llama al enviar el formulario y utiliza la función setSubmitting para actualizar el estado del componente Formik durante el envío.

<Formik
   initialValues={{ username: "", email: "", password: "" }}
   // . . .
   onSubmit={(values, { setSubmitting }) => {
     setTimeout(() => {
       console.log(JSON.stringify(values, null, 2));
       setSubmitting(false);
     }, 400);
   }}
>
Conclusión
Formik es una de esas bibliotecas de código abierto que son necesarias cuando se escriben muchos formularios en una aplicación de React. Hace que el proceso de creación de formularios sea relativamente rápido e intuitivo, especialmente al crear formularios complejos.

En este artículo, hemos cubierto las características principales de la biblioteca. Si deseas obtener más información sobre Formik, puedes encontrar información adicional en la documentación oficial de la biblioteca.
Conviértete en un desarrollador frontend profesional desde cero en 10 meses:

En Códica, ofrecemos la profesión de Desarrollador Frontend. Realiza este curso para aprender uno de los lenguajes de programación más populares, dominar los frameworks populares y crear un gran portafolio de proyectos en GitHub.
Leer otros artículos de Blog
Lee otros artículos relevantes del mundo de la tecnología y el espíritu empresarial.