React — Formularios con React.Component (Input, Textarea, Select, Radio, Checkbox)
Temario
- Introducción
- Componentes no controlados, controlados
- Múltiples entradas del formulario
- Creando el componente Input
- Creando el componente Textarea
- Creando el componente Select
- Creando el componente Radio
- Creando el componente Checkbox
i. Introducción
¿Qué sería de las aplicaciones web sin los formularios?, desde que inicie a desarrollar aplicaciones siempre he hecho formularios, en esta story vamos a ver formularios con React, pero desde cero a un nivel (quizás) medio, así que pónganse cómodos…
Antes de continuar te recomiendo que veas la story pasada (Crear un proyecto básico en codesandbox.io [ref]), para que puedas crear el proyecto online.
ii. Componentes no controlados y controlados
Crear un formulario en HTML, es algo así:
En React contamos con dos diferentes comportamientos:
— No controlado (uncontrolled input)
Los elementos de formularios de manera natural mantienen sus propios estados y se actualizan de acuerdo a la interacción del usuario, de hecho muchas veces tienen comportamientos predeterminados (ej. cuando se le da click a un botón y hace el submit, su comportamiento es enviar los datos a otra página).
Para usarlos en React, realmente son como los formularios que ya conocemos en HTML, donde usamos el atributo ref para obtener los valores del formulario:
Lo que hacemos es agregar el atributo ref y un nombre identificador, para acceder a los valores desde this.refs cuando se envía el formulario. La desventaja es que React no tiene el control sobre el estado del formulario y componentes y cada vez que necesitamos saber de un valor, debemos pedirlo.
— Controlado (controlled input)
En React, el estado mutable es mantenido normalmente en la propiedad estado de los componentes, y solo se actualiza con el método setState(), es decir, a medida que cambia el valor del formulario, el componente que representa el formulario guarda el valor en su estado.
De esta forma hacemos que los datos “verdaderos” sean los que maneja React, y así va a controlar el renderizado del formulario y las interacciones del usuario.
Por lo tanto, el componente siempre va a tener el valor actual de cada campo sin necesidad de solicitarlo, por lo que el componente puede responder inmediatamente a los cambios (ej. bloquear botones, validaciones al instante, cambió el flujo de preguntas, etc).
Ejemplo completo:
iii. Múltiples entradas del formulario
En el ejemplo pasado, estamos teniendo varias entradas del formulario, por lo que tenemos que crear n métodos para leerlos todos:
Y conforme va creciendo el formulario, deberíamos ir agregando más métodos, más binds, pffff, mucho trabajo….así que vamos a buscar la forma de tener una sola entrada para todos, para eso, vamos a crear un método genérico o universal, donde lea el nombre del campo y su valor:
Aquí usamos el nombre de la propiedad computada[ref], con esto nos da la oportunidad de actualizar el estado de manera dinámica.
Ahora, si bien el método de arriba esta genial, aún le faltan algunos detalles, si nosotros hacemos el cambio, así tal cual:
Podemos observar que solo nos esta guardando el último valor capturado, entonces, lo que nos hace falta es persistir todos los campos, entonces hagamos un pequeño cambio:
Lo que hacemos es ocupar el operador spread[ref], para separar todos los valores.
Pero, ahora que pasaría si además de tener el valor, necesito persistir más propiedades, a lo mejor el tipo de campo, o la descripción, entonces adaptemos nuestro código:
Al igual que en el formulario, aplicamos el operador spread[ref], para separar todos los valores.
Veamos nuestro ejemplo completo:
Veamos la siguiente animación (viene directo de codesandbox, donde tiene su propio devTools para React, pero si usan chrome, pueden usar la siguiente extensión [ref])
iv. Creando el componente Input
Uno de los campos más importantes dentro de un formulario es el input, así que vamos a crear uno básico y progresivamente le iremos añadiendo complejidad, entonces, el componente más básico es:
Vamos a darle un poco más de forma, la idea es de que agreguemos por medio de propiedades algunos atributos importantes:
No hay nada de novedoso, solo estamos aprovechando todo lo que hemos aprendido acerca de React.
Nuestro siguiente paso es generar un componente Form, para ir haciendo desde ahí los cambios que necesitamos:
Por ahora, no hace nada interesante, de hecho hasta aquí es un componente no controlado, ya que a pesar de estar usando el estado para mandar los atributos, en ningún momento estamos teniendo el control de lo que escribe el usuario, entonces el siguiente paso es precisamente eso… actualizar el estado.
Perfecto, nuestro formulario se ha vuelto un componente controlado.
Aumentemos un poco la complejidad. La idea es poder agregar validaciones dinámicas al componente, donde nos regrese una bandera de 1 ó 0, entonces antes de hacer eso, primero crearemos un archivo helper, donde tendremos un método validate, que acepte dos parámetros (value, rules) y lo siguiente será recorrer las reglas, para validarlas contra el valor que nos han dado, en caso de que todo esté bien, regrese un 1, caso contrario 0.
Nota: Solo es un ejemplo para validar campos, estoy seguro que le faltan muchas reglas, y aún más seguro que se pueden optimizar, pero para nuestro ejemplo, está perfecto.
Nuestro proyecto debe verse algo así:
Ahora, sí el primer cambio lo haremos en el estado, agregando las propiedades (valid, validationRules)
Realicemos los cambios que faltan:
- Importar el archivo de validations
- Hacer la validación del valor
- Actualizar el estado del componente
Si hemos hecho todo bien hasta aquí, debemos de ver algo así:
Ya hemos validado el valor que captura el usuario, pero, aún nos falta indicarle de alguna manera, que lo que está capturando no es válido, entonces haremos lo siguiente:
- Cuando no sea válido el campo, lo vamos a poner el borde de rojo
Lo primero que haremos es pasarle a nuestro componente el atributo valid:
En el archivo style.css, agregamos lo siguiente:
Ahora, en nuestro componente Input, vamos hacer la validación:
Pero tenemos un pequeño problema, cuando entra la primera vez, ya sale marcado:
En el componente From, agregamos la propiedad touched (como lo hicimos con valid), y en nuestro componente Input, lo agregamos a la validación (como lo hicimos con valid):
Si lo hemos seguido los pasos correctamente, debemos ver algo parecido a la animación:
Ejemplo completo:
v. Creando el componente Textarea
La sintaxis del textarea en HTML es de la siguiente manera[ref]:
Podemos observar que es muy parecido en características al Input, entonces, quedaría de la siguiente manera:
Al ser muy similar al Input, podemos aprovechar todas las propiedades, entonces en nuestro componente Form, lo agregamos al estado:
Lo agregamos a nuestro JXS:
Importante: No olviden importar el componente
Ejemplo completo:
vi. Creando el componente Select
La sintaxis del selector en HTML es de la siguiente manera[ref]:
Sabemos que recibimos una lista de opciones, entonces, en nuestro componente debemos recorrer dichas opciones e irlas agregando, nuestro componente quedaría de la siguiente manera:
La otra alternativa es ponerlo en una variable:
En nuestro componente Form, solo debemos crear un estado para el selector, donde tenga opciones:
Lo agregamos a nuestro JXS:
Importante: No olviden importar el componente
Ejemplo completo:
vii. Creando el componente Radio
La sintaxis del radio en HTML es de la siguiente manera[ref]:
Podemos observar que la idea va a ser similar al selector, nuestro componente quedaría de la siguiente manera:
En nuestro componente Form, solo debemos crear un estado para el radio, donde tenga opciones:
Lo agregamos a nuestro JXS:
Importante: No olviden importar el componente
Ejemplo completo:
viii. Creando el componente Checkbox
La sintaxis del checkbox en HTML es de la siguiente manera[ref]:
Si vemos es muy parecido al Input, entonces, así quedaría nuestro componente:
En nuestro componente Form, solo debemos crear un estado para el checkbox:
Lo agregamos a nuestro JXS:
Importante: No olviden importar el componente
Ejemplo completo:
Y para obtener los valores, solo basta recorrer el estado, con cada una de las propiedades…
Todavía podemos hacerle muchas mejoras, quizás habilitar / deshabilitar un botón de enviar, a lo mejor que muestre un mensaje debajo de cada campo, indicando que esta mal, hacer que el componente Checkbox acepte un grupo.
React nos recomienda: Si lo que estás buscando es una solución completa incluyendo validación, tener en cuenta los campos visitados y manejar el envío del formulario, Formik es una de las opciones populares.
En la siguiente entrega vamos a ver React — Hooks [useState, useEffect, useContext](Parte I)
La entrega pasada vimos React — Crear un proyecto básico en codesandbox.io
Bibliografía y links que te puede interesar…