Gabriel Jiménez | Hace alrededor de 1 mes
El objetivo del artículo es aprender las partes esenciales de integrar librerías de creación de formularios como React Hook Form con librerías de estilos como MUI.
Los formularios son de los elementos más utilizados en las aplicaciones frontend: web, móvil y de escritorio. Sin embargo, a veces no se les da la importancia que debería, porque se cree que solo es agregar inputs, ponerlos bonitos y enviaros al backend.
Vamos a ver como esto puede ser un reto y como librerías como React Hook Form y MUI, facilitan su creación.
La lista puede ir incrementando dependiendo las características del proyecto, por eso librerías como React Hook Form y Material UI son de gran ayuda.
Las librerías como React Hook Form se encargan de gestionar todo el proceso de envío de formulario — como vimos en la figura 1.
Entre las ventajas que podemos encontrar son:
Si quieres saber como crear un formulario con React Hook Form, te invito a leer mi artículo: Tu primer formulario en React con React Hook Form.
Las librerías de estilos son muy útiles para agilizar el diseño de nuestras páginas. Muchas de ellas, ya tienen componentes desarrollados con estilos bien definidos, lo que facilita integrarlos en nuestros proyectos. Además que, muchas ya se encargan de la parte responsiva.
Material UI es una librería de estilos muy completa entre sus ventajas tenemos:
Para trabajar este proyecto, utilizaremos Create React App que es una librería para crear aplicaciones React de tipo sigla-page con la más mínima configuración. También, instalaremos React Hook Form y Material UI.
Para crear un proyecto usando Create React App solo hay que ejecutar los siguientes comandos en nuestra terminal.
npx create-react-app my-app cd my-app npm start
Al final tendremos una servidor escuchando en el puerto localhost:3000
Para instalar React Hook Form y Material Ui, hay que ejecutar los siguientes comandos:
React Hook Form
npm install react-hook-form
Material UI
npm install @mui/material @emotion/react @emotion/styled
Listo, ya tenemos todo necesario.
Para entender las ventajas de utilizar React Hook Form y MUI, desarrollemos un ejercicio de un formulario sin utilizar ninguna librería externa —únicamente React, y aprendamos que problemas solucionan cada una de estas librerías.
Comencemos implementando el formulario sin librerías externa:
1: import React from 'react' 2: 3: function App() { 4: const [values, setValues] = React.useState({ producto: '', descripcion: '' }) 5: const [errors, setErrors] = React.useState({}) 6: 7: function validate(v) { 8: const e = {} 9: if (!v.producto?.trim()) e.producto = 'El producto es obligatorio' 10: if (!v.descripcion?.trim()) e.descripcion = 'La descripción es obligatoria' 11: return e 12: } 13: 14: function handleChange({ target }) { 15: const { value, name } = target 16: setValues({ ...values, [name]: value }) 17: } 18: 19: function handleSubmit(e) { 20: e.preventDefault() 21: const eObj = validate(values) 22: setErrors(eObj) 23: 24: if (Object.keys(eObj).length === 0) { 25: console.log('Envío de data: ', values) 26: } 27: } 28: 29: return ( 30: <form onSubmit={handleSubmit}> 31: <input 32: type="text" 33: name="producto" 34: value={values.producto} 35: onChange={handleChange} 36: placeholder="Producto" 37: /> 38: {errors.producto && <div>{errors.producto}</div>} 39: 40: <textarea 41: name="descripcion" 42: value={values.descripcion} 43: onChange={handleChange} 44: placeholder="Descripción" 45: /> 46: {errors.descripcion && <div>{errors.descripcion}</div>} 47: 48: <button type="submit">Enviar</button> 49: </form> 50: ) 51: } 52: 53: export default App
Este ejemplo es bastante sencillo, pero podemos detectar varios problemas:
Veamos como React Hook Form y MUI, nos ayuda a solventar estos problemas.
React Hook Form
1: import React from 'react' 2: import { useForm } from 'react-hook-form' 3: 4: function App() { 5: const { register, handleSubmit, formState: { errors } } = useForm({ 6: defaultValues: { 7: producto: '', 8: descripcion: '' 9: } 10: }) 11: 12: function onSubmit(values) { 13: console.log('Envío de data:', values) 14: } 15: 16: return ( 17: <form onSubmit={handleSubmit(onSubmit)}> 18: <input 19: type="text" 20: {...register('producto', { required: 'El producto es obligatorio' })} 21: /> 22: {errors.producto && <div>{errors.producto.message}</div>} 23: 24: <textarea 25: {...register('descripcion', { required: 'La descripción es obligatoria' })} 26: /> 27: {errors.descripcion && <div>{errors.descripcion.message}</div>} 28: 29: <button type="submit">Enviar</button> 30: </form> 31: ) 32: } 33: 34: export default App
Al usar React Hook Form tenemos lineamos para:
Material UI
1: import React from 'react' 2: import { useForm } from 'react-hook-form' 3: import TextField from '@mui/material/TextField' 4: import Button from '@mui/material/Button' 5: 6: function App() { 7: const { register, handleSubmit, formState: { errors } } = useForm({ 8: defaultValues: { 9: producto: '', 10: descripcion: '' 11: } 12: }) 13: 14: function onSubmit(values) { 15: console.log('Envío de data:', values) 16: } 17: 18: return ( 19: <form onSubmit={handleSubmit(onSubmit)}> 20: <TextField 21: label="Producto" 22: {...register('producto', { required: 'El producto es obligatorio' })} 23: error={!!errors.producto} 24: helperText={errors.producto?.message} 25: /> 26: 27: <TextField 28: label="Descripción" 29: multiline 30: rows={3} 31: {...register('descripcion', { required: 'La descripción es obligatoria' })} 32: error={!!errors.descripcion} 33: helperText={errors.descripcion?.message} 34: /> 35: 36: <Button type="submit" variant="contained"> 37: Enviar 38: </Button> 39: </form> 40: ) 41: } 42: 43: export default App
Perfecto, ahora ya tenemos componentes con un mismo estilo.
Para mantener un estándar de estilos en nuestras aplicaciones, podemos usar los templates o encapsular la estructura de estilos en un nuevo componente, por ejemplo:
const MiTextArea = ({...muiProps }) => { return( <TextField { ... muiProps } multiline rows={3} /> ) }
De esta forma, establecemos que siempre los TextArea tendrán tres filas.
Si quieres aprender a crear formularios más escalables, revisa mi artículo: Formulario en React con MUI, guía para principiantes.
Al utilizar librerías de terceros podemos agilizar nuestros desarrollos, al facilitar lineamos bien estructurados para formularios. Sin embargo, es importante diseñar antes de implementar en nuestros proyectos.
Para aprender más sobre cómo crear formularios más avanzados, te recomiendo mi libro: Testing en React: Guía práctica con Jest y React Testing Library.