Los formularios son un tema importante porque son extremadamente comunes en las aplicaciones que construimos. En este artículo, aprenderemos cómo crear formularios usando componentes controlados por React y veremos cómo construir componentes genéricos para ayudarnos a minimizar y optimizar el código.
Además, la validación del lado del cliente es fundamental para la experiencia del usuario de los formularios que construimos, por lo que también cubriremos este tema. Enviar el formulario también es una consideración crítica. Cubriremos cómo manejar los errores de envío, así como el éxito de una forma genérica.
Por lo que, en esta serie de artículos, vamos a cubrir los siguientes temas:
En React, librería de JavaScript que ya hemos visto en artículos anteriores, nosotros podemos usar componentes controlados para implementar un formulario, un componente controlado tiene su valor sincronizado con el estado en React, por medio de la función useState, que es parte de la API de Hooks.
En el ejemplo que mostraremos más abajo, Articulo.tsx, hemos realizado las siguientes acciones:
Si no contásemos con un componente genérico tendríamos que estar repitiendo todo este código constantemente en cada una de las pantallas que se necesiten formularios, crear estados, detectar eventos de cambios de valores en los inputs, checkbox, validación de campos y todo tipo de código que nos podríamos ahorrar y optimizar con la creación de un componente genérico.
Es importante puntualizar, que para este artículo vamos a usar React y TypeScript juntos. React se define en sí mismo como una librería JavaScript de código abierto creada por Facebook para construir interfaces de usuario, sin embargo, cuando le sumamos el ecosistema de herramientas disponibles, es una solución completa para el desarrollo de aplicaciones web, móvil, escritorio e incluso realidad virtual.
Con React nosotros podemos dividir nuestra aplicación en pequeños componentes reusables, componentes los cuales pueden tener su propia interface de usuario y comportamiento.
React es una librería progresiva, es decir, aumentar la integración de componentes y frameworks en función de nuestras necesidades, por lo que se adaptará perfectamente a nuestro proyecto.
Partiendo de la base de que la curva de aprendizaje en React es más baja en comparación con otros frameworks/librerías, es importante tener conocimientos básicos de HTML, CCSS y JavaScript y para este artículo en concreto sería interesante disponer de conocimientos básicos de TypeScript.
TypeScript no ofrece la posibilidad de tipar los datos, por tanto, nos proporciona un mayor control en tiempo de ejecución de todo nuestro código.
Por ejemplo:
const miVariableTexto: string;
const miVaribleNumero: number;
Cómo comentábamos anteriormente, en este artículo aprenderemos cómo crear formularios genéricos para ayudarnos a minimizar, reutilizar en otros proyectos con el consiguiente incremento de productividad y optimizar nuestro código gracias a la reutilización de nuestros componentes, todo ello, usando React y TypeScript.
En esta sección, vamos a crear un componente formulario genérico (FormGenerico.tsx) y componente campo genérico (FieldGenerico.tsx) que se encargará de manejar el estado de los valores (inputNameValue/setInputNameValue y inputApellidoValue/setInputApellidoValue), detección de eventos, validación de campos, etc, que hemos implementado anteriormente en Articulo.tsx , esto reducirá drásticamente el código necesario para implementar un formulario.
export interface Values {
[key: string]: any;
}
En este caso, la key será el nombre del campo y el value será el valor del campo, ejemplo:
{
nombre: “valor del input nombre”,
apellido:”valor del input apellido”
}
const [values, setValues] = useState<Values>({});
Establecemos el estado inicial en un objeto literal vacío, values dispondrá de todos los valores de todos los inputs, en nuestro ejemplo la clave/valor del objeto sería:
{
nombre: “valor del input nombre”,
apellido:”valor del input apellido”
}
El componente FieldGenerico, no deja de ser todo elemento que puede formar parte de un formulario, Input, Select, TextArea, Checkbox, etc. Así como conjunto de dichos elementos que sean usados a su vez como componentes en este FieldGenerico, al final, la esencia es la misma, mientras más componentes tengamos que puedan ser reutilizados, más productivos, mejor calidad de código y más control sobre nuestra aplicación tendremos.
Los pasos a seguir son:
interface Props {
name: string;
label?: string;
type?: 'Text' | 'TextArea';
}
{(type === 'Text') && (
<input
type={type.toLowerCase()}
id={name}
....
)}
{type === 'TextArea' && (
<textarea
id={name}...
Es importante destacar que el estado de los valores de un campo, se encuentra en el componente FormGenerico, pero se presenta y cambia en el componente FieldGenerico.
Gracias a React Context, FormGenerico puede compartir su estado con FieldGenerico, con context de React se posibilita pasar datos a través del árbol de componentes, sin tener que pasar propiedades manualmente en cada nivel, en este caso FormGenerico provee y FieldGenerico consume los valores que presenta FormGenerico.
En este punto, nos centraremos en quien provee, quien es la fuente de los valores que serán consumidos por el componente genérico FieldGenerico.
import { FC, useState, createContext } from 'react';
interface FormContextProps {
values: Values;
setValue?: (fieldName: string, value: any) => void;
}
Nuestro context contendrá los valores del FormGenerico y la función para actualizarlos
export const FormContext = createContext<FormContextProps>({
values: {},
});
Ahora que ya hemos tenemos creado el contexto en FormGenerico, vamos a usar su componente Provider.
<FormContext.Provider
value={{
values,
setValue: (fieldName: string, value: any) => {
setValues({ ...values, [fieldName]: value });
},
...
De esta manera, utilizamos su componente Provider, para dar acceso a dicho contexto a sus componentes hijos (FieldGenerico), para que puedan ser consumidos.
Y aquí acaba la primera parte de esta sección de artículos sobre cómo crear componentes genéricos con React y TypeScript para reducir el código repetitivo en nuestros proyectos.
Te esperamos en la segunda parte, en la que detallaremos cómo consumir un Context de FormGenerico, cómo implementarlo y en la que contaremos con un ejemplo completo.