Las ventajas que te ofrece Microsoft Azure y el mundo.NET

Redux-Form: Pon orden a tus formularios

La utilización de una u otra librería para la parte del Front-End de los desarrollos que hemos implementado, es algo que decide cada desarrollador. Esto nos proporciona una gran libertad, pero también una gran responsabilidad. La elección de una mala librería es problema del desarrollador y por lo tanto, los errores o bugs que pueda tener, serán problema de quien utilice esta librería. En este artículo vamos a ver si en nuestros desarrollos deberíamos incluir Redux Form, cuáles son sus pros y sus contras.

Desde hace más de un año seleccionamos ReactJS como la librería utilizada para la parte Front-End de los desarrollos que hemos implementado. Una de sus principales ventajas es la posibilidad de elegir cada parte de nuestro desarrollo, ReactJS se encarga solo del renderizado del HTML.

Hace una única cosa y la hace muy bien. Junto con ReactJS hay una serie de librerías que complementan todo lo que nos proporciona un Framework Javascript: react-redux, react-router, react-thunks…

Qué es Redux-Form

Partiendo de está introducción, en nuestros desarrollos estábamos teniendo un problema a nivel de mantenimiento del código en todos los componentes React que se comportan como Formularios. Para implementar este componente, tenemos una serie de elementos en su estado que hay que controlar. Todo esto, hace que cuando el formulario tiene muchos campos y se requieren una serie de validaciones, el número de líneas crece exponencialmente.

Para intentar solucionar este problema, nos planteamos:

  • Intentar incorporar una libreria de validaciones
  • Crear componentes con dicha funcionalidad
  • Incorporar React-Redux

Descartamos incorporar una librería de validaciones porque suponía añadir una dependencia extra, y no nos terminaba de convencer su funcionamiento.

La segunda opción (crear componente con dicha funcionalidad), nos pareció una muy buena opción debido a que nosotros teníamos todo el control del desarrollo, pero parecía que estábamos reconstruyendo la rueda y añadiendo una dificultad extra a nuestros desarrollos.

Consideraciones previas

En medio de esta situación, probamos Redux-Form…pero antes de empezar a hablar sobre esta librería vamos a hacer algunas aclaraciones:

  • Está vinculado a la librería react-redux, por lo que si no utilizas esta librería para implementar una arquitectura “Flux”, no la puedes utilizar (a no ser que hagas  modificaciones).
  • No es una librería que nos sirva unos formularios predefinidos. El desarrollo de los formularios lo tenemos que hacer nosotros. Quizá el nombre lleve a equivocación.
  • Utiliza el patron Hight Order Componente (aka llamado Matriuska).
  • Se intregra con la Store.

Beneficios

El gran beneficio que nos reporta esta librería, es que pone orden al código para utilizar en los formularios.  Por un lado tenemos un componente Formulario que es el que vinculamos con nuestra store. Por otro lado tenemos una serie de componente para poder tener cada campo con una validación. Y por si fuera poco, todas estas reglas se pueden compartir entre los mismos campos, por ejemplo tenemos una función que nos valide un DNI y esta regla la podemos utilizar en más campos.

El Flujo de nuestra aplicación quedaría de la siguiente forma:

redux form flow

Show me the code, talk (write) is cheap

Para empezar, en  nuestra solución incorporaremos las librería redux-form y sus tipos correspondientes (debido que durante el desarrollo hemos optado por usar  Typescript en lugar de Javascript directamente). Para ello, en el package.json de nuestro proyecto añadiremos estas dependencias:

 @types/redux-form": "^7.4.6",
 redux-form": "^7.4.2"

Otra forma de incorporar estas dependencias es  instalando estos paquetes con npm y la opcion –save-dev.

Una vez tenemos la solución lista,  creamos nuestro formulario. En primer lugar, vamos a crearnos un componente personalizado extendiendo la funcionalidad Field que nos proporciona la librería en el que vamos a configurar, por un lado las reglas de validación que va a tener el campo, la etiqueta, el mensaje de error de validación. Un ejemplo sería el siguiente código:

const email = (value:any) =>
  value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)
    ? 'Invalid email address'
    : undefined
const alphaNumeric = (value:any) =>
  value && /[^a-zA-Z0-9 ]/i.test(value)
    ? 'Only alphanumeric characters'
    : undefined
export const phoneNumber = (value:any) =>
  value && !/^(0|[1-9][0-9]{9})$/i.test(value)
    ? 'Invalid phone number, must be 10 digits'
    : undefined

const renderField = (props:any) => (
  <div className="col-md-3 col-sm-3 aitscontactw3l-grid aitscontactw3l-grid-1">
    <label className="fill fill-top">{props.label}</label>
      <input className="fill" {...props.input} placeholder={props.label} type={props.type} />
      {props.touched &&
        ((props.error && <span>{props.error}</span>) ||
          (props.warning && <span>{props.warning}</span>))}
  </div>

Con este campo personalizado y con estas reglas de validación, ya podemos empezar a crear el formulario. Para ello lo que vamos a utilizar es el componente Field,  que se comportará según nuestros criterios, es decir: qué reglas de validación van a tener, cuál es su diseño, etc.

Por otro lado en este componente también vamos a ver cual es el funcionamiento que queremos hacer una vez nuestro formulario sea válido. Un ejemplo de un formulario de suscripción a un rss podría ser de la siguiente forma:

onst ContactForm = (props:any) => {
  const { handleSubmit } = props
  return (
    <div className="aitscontactw3l" id="aitscontactw3l">
      <div className="container">
        <h3>Contacto</h3>
   <form onSubmit={handleSubmit}>
              <Field  
               type="email"
               name="Email" 
               component={renderField} 
               label="Correo electronico"
               validate={[required, email]}
               warn={alphaNumeric} />
              <input className="submit" type="submit" value="Enviar" />
                <div className="clearfix"/>
        </form>
      </div>
    </div>
  )

Una vez ya tenemos el formulario, tenemos que registrarlo en la librería para que se pueda utilizar como un elemento más dentro del flujo de la aplicación.

export const Form = reduxForm({
  // a unique name for the form
  form: 'contact'
})(ContactForm)

Como ya hemos comentado, el nombre de form debe de ser único, es decir, si damos de alta dos formularios con el mismo identificador, la librería no funciona.

Uno de los aspectos que he esbozado al inicio del artículo, es que Redux-Form hace uso del patrón hight order component. Esto lo podemos comprobar porque ahora mismo, hemos creado un componente y éste va a estar incluido en un componente superior desde el cual se le van a pasar las props (en forma de Matriuska). Por lo que en nuestro desarrollo lo que vamos a realizar es crearnos un componente principal que será el encargado de pasarle los métodos de ejecución al hijo. Un ejemplo del anterior sería el siguiente código:

export class Contact extends React.Component<{}, {}> {
  public submit = (values:any) => {
    console.log(values)
  }
  public render() {
    return <Form onSubmit={this.submit} />
  }
}

Por último para poder incluir Redux-Form en el contexto de Redux lo que tenemos que hacer es incluirlo dentro de los Reducers correspondiente. La librería ya trae de serie un reducer “formReducer” que es el que vamos a utilizar.

import { reducer as formReducer } from 'redux-form'
export interface IStateReducer {
carrousel:ICarrouselItem[],
form:any
}

export const state = combineReducers<IStateReducer>({
  carrousel: carrouselReducer,
  form: formReducer
});

¿Aún hay más?

La librería aun tiene mucha más funcionalidad avanzada, por ejemplo puede hacernos agrupaciones de campos para aplicar validaciones. También tiene funcionalidad para poder implementar un Wizard. Con esta herramienta hace todo de una forma más sencilla.

Resumen

Redux Form es una librería que nos facilita la posibilidad de establecer el orden de nuestra solución para todos los componentes que se comporten de tipo formulario. Esto hace mucho más fácil su posterior mantenimiento y evolución.

Otra de las grandes ventajas es que lo tenemos incorporado a Redux, lo que hace que todo siga el mismo patrón Flux. En definitiva, a la hora de incorporar librerías de terceros siempre hay que pensarlo muy detenidamente porque nos puede ocasionar problemas futuros. Sin embargo, Redux Form es una librería bastante buena que nos aporta numerosos beneficios y en el caso de formularios complejos, nos facilita mucho la vida 😊

mm

Sobre Adrián Díaz

Adrián Díaz es Ingeniero Informático por la Universidad Politécnica de Valencia. Es MVP de Microsoft en la categoría Office Development desde 2014, MCPD de SharePoint 2010, Microsoft Active Profesional y Microsoft Comunity Contribuitor 2012. Cofundador del grupo de usuarios de SharePoint de Levante LevaPoint. Lleva desarrollando con tecnologías Microsoft más de 10 años y desde hace 3 años está centrado en el desarrollo sobre SharePoint. Actualmente es Software & Cloud Architect Lead en ENCAMINA.
Esta entrada ha sido publicada en ReactJS, Redux-Form y etiquetada como , , , . Enlace permanente .
Suscríbete a Piensa en Sofware desarrolla en Colores

Suscríbete a Piensa en Sofware desarrolla en Colores

Recibe todas las actualizaciones semanalmente de nuestro blog

You have Successfully Subscribed!

ENCAMINA, piensa en colores