Introducción
Los Componentes de React están pensados para la generación de vistas para la UI. Estos pueden contener valores de State y/o recibir Props. Usualmente, cuando queremos reutilizar un Componente (o partes del mismo) declaramos Props para que sea el Componente contenedor el que indique qué valor será el utilizado en ese momento; mientras que si lo que buscamos es que un Componente altere la vista por sí mismo le declaramos un valor de State para ser modificado.
Los Componentes que cambian producto de los valores de Props son conocidos como Componentes Controlados porque dependen de un Componente externo para saber cómo deben actuar.
Los Componentes que se modifican producto de la interacción con un valor de State propio son conocidos como Componentes No Controlados porque no necesitan de ningún interventor para generar un cambio en la vista.
Estas nociones pueden ser aplicadas al trabajo con formularios. Para entender cómo vamos a analizar el trabajo con formularios en JS Vanilla que implica tres cosas. Primero, un Evento para indicar cuándo vamos a interactuar con el elemento (onclick, onblur, onchange, onsubmit, etc.); segundo, en el momento elegido, tomar el elemento usando alguna de las funciones que nos permitan almacenar el Objeto HTML (getElementByID, querySelector, etc.); y, por último, usar ese Objeto HTML para leer el dato ingresado por el usuario.
Dentro de esa secuencia de pasos podemos distinguir una característica fundamental de los elementos de formulario. Contienen una variable con un valor inicial que es modificado producto de la interacción del usuario con el mismo. Es decir, un elemento de formulario tiene su propio valor de state. Por lo tanto, y teniendo en cuenta la caracterización antes hecha sobre los tipos de Componentes. En React, es posible hablar de Formularios Controlados y Formularios No Controlados
Formularios No Controlados
Un Formulario No Controlado es aquel que no se relaciona con el Componente que lo contiene. En estos casos, el Componente recupera la información almacenada en el State del elemento Input cuando sea necesario. Para ello, y teniendo en cuenta que todos nuestros Componentes interactúan con el virtualDOM, necesitamos acceder al elemento input que se encuentra en el DOM real. Eso lo logramos usando refs.
¿Qué es una refs?
Las refs son una forma de trabajar “fuera de React”. Como ya dijimos, toda la lógica de programación que planteamos en nuestros Componentes tienen como objetivo indicarle al virtualDOM qué vista estamos queriendo crear y, por tanto, ninguna interacción planteada va a manipular directamente el DOM real. Pero existen casos en los que, por algún motivo, necesitamos acceder al nodo del DOM. Para eso están las refs.
El uso del Hook useRef (React.createRef() en Componentes de Clase) genera un Objeto con una única propiedad: la propiedad current. Inicialmente current es null. Ese valor es reemplazado por la referencia al nodo del DOM una vez que este es insertado por el virtualDOM. Por este motivo, la forma más segura de utilizar las refs es dentro de la callback de un Evento.
Hay que tener en cuenta que cualquier manipulación que hagamos del nodo del DOM empleando las refs puede generar errores con los Componentes que trabajan “dentro de React”. Por lo tanto, lo más recomendable es usar las refs para aquellos casos en los que necesitemos realizar alguna acción que no genera cambios de vista. Por ejemplo: hacer scroll a un elemento o leer el value de un input
¿Cuándo conviene crear refs para trabajar con formularios?
Si vamos a hacer una validación del formulario en el Evento submit o si vamos a usar un input para permitir que el usuario ingrese un valor en particular, el uso de refs y, en consecuencia, la creación de un formulario no controlado es perfecto
Ejemplo
Formularios Controlados
Los Formularios Controlados están pensados para manipular las vistas del Componente que los contienen, por eso es necesario que dicho Componente genere un valor de State pensado específicamente para almacenar el value del input. De esta forma, la manipulación de dicho input generará la nueva vista. Este tipo de formularios es perfecto para todos aquellos casos en que la manipulación del mismo genera cambios en los distintos Componentes de nuestra app.
Para armar un Formulario Controlado debemos agregar el "atributo" input (o checked en caso de checkbox y radio) y almacenar el valor del state correspondiente para ese input. Además, debemos asegurarnos de mantener el State actualizado según los valores almacenados en el State del input, por lo que vamos a necesitar agregar un Evento change que se encargue de dicha actualización.
¿Cuándo conviene trabajar con Formularios Controlados?
Los Formularios Controlados son los que más vamos a estar utilizando (de hecho, en su documentación oficial React recomienda su uso por sobre los Formularios No Controlados), por eso no podríamos hablar de casos concretos. Igualmente, el uso más común es cuando necesitamos hacer disponibles los valores ingresados en otro Componente.
Ejemplo
Formularios Controlados vs. No Controlados
A continuación te dejo una tabla con escenarios en los que usaríamos los distintos tipos de formularios
Conclusión
Los formularios no controlados son simples de armar y nos permiten tomar los valores de input de forma imperativa. Ideales para trabajos que no requieran manipulación de la interfaz de usuario.
Los formularios controlados pueden ser bastante engorrosos de armar y manipular, pero al atar los valores de state de los inputs al state del Componente son ideales para todo trabajo que implique manipular la vista como consecuencia de los datos ingresados.
Redes