Formularios en React: ¿Cómo manejar los formularios en React.js con input controlados y no controlados?
by Juan Carlos García
3-Mzo-2023
(2)
Suscribirme al canal:
Hola de nuevo viajero, hoy vamos a continuar con este curso de React JS y el tema que tocaremos el día de hoy es referente al Manejo de Formularios en React, este es un tema sumamente importante ya que prácticamente en toda página web vas a necesitar de al menos un formulario.
Cabe aclarar, que en este primer post veremos las formas en que podemos manejar formularios sin ocupar librerías de terceros, si este curso recibe bastante apoyo, iré complementando con algunas librerías que existen y que en algunos casos suelen ser de utilidad.
- Si aun no has visto el capítulo anterior sobre Listas y condiciones en React, por favor revísalo para que vayas en orden y aprendas cada concepto.
¡No te puedes perder las nuevas clases 🧐!
¿Que es React JSX?
Guía para principiantes de React JSX: ¿Qué es React JSX? Introducción a React JSX
(8)
Componentes y propiedades
Components and Props React.js, Manejo de propiedades y componentes en React
(4)
State y Ciclo de vida en React
State And Lifecycle: Comprendiendo el State y Ciclo de vida de los componentes en React.js
(4)
Refs React
¿Qué son las React Refs y para que sirven? Uso de las Refs y manejo del DOM en React.js
(1)
Listas y condiciones en React
Keys and List: ¿Cómo manejar las listas y condicionales en React JS?
(2)
Formularios en React
Formularios en React: ¿Cómo manejar los formularios en React.js con input controlados y no controlados?
(2)
React develepor tools
React Developer Tools: ¿Cómo analizar el comportamiento y estado de nuestros componentes en React.js?
(2)
API Context
API Context en React: ¿Cómo comunicar componentes mediante API Context en React.js?
(3)
Children en React JS
Children en React.js: Manejo avanzado de Children en React.js, composición de componentes.
(3)
PropTypes en React
PropType en React.js: ¿Cómo validar datos a través de PropType en React.js?
(2)
Hooks en React JS
Master de Hooks en React JS: ¿Qué es un Hook en React.js? Tipos, funcionamiento y características.
(1)
Hook useEffect
Hook useEffect: ¿Qué es el Hook useEffect? ¿Cómo utilizarlo correctamente y qué reglas seguir?
(5)
Hook useContext
¿Cómo utilizar el Hook useContext? Comunicación de componentes funcionales
(4)
🧐 Autoevaluación: Formularios en React
¿Qué son los input no controlados?
¿Qué son los input controlados?
Tabla de contenido
- 1 ¿Qué aprenderás del manejo de formularios en React JS?
- 2 Manejo de formularios en React
- 3 Componentes controlados y no controlados
- 4 Inputs no controlados
- 5 Ventaja y desventaja de utilizar componentes no controlados
- 6 Inputs controlados
- 7 Creando input tipo text controlado
- 8 Creando input tipo Checkbox controlado
- 9 Creando input tipo select controlado
- 10 Creando un form con inputs controlados
- 11
¿Qué aprenderás del manejo de formularios en React JS?
- Utilización de inputs no controlados a través de refs
- Recuperar datos de input no controlados a través de eventos
- Creación de inputs controlados
- Aprenderás a desarrollar un formulario listo para agregarlo a tu proyecto
- Conocerás una de las formas en que puedes validar los datos de tu formulario
- Y mucho más.
Repositorio:
- Este capitulo lo puedes descargar clonando el repositorio con la siguiente línea de código.
- Y solo debes cambiarte a la rama de nombre "formularios"
- Si no estas familiarizado con Git, descarga el código aquí.
- Recuerda que cada capítulo estará en una rama diferente para llevar un orden
git clone https://github.com/EWebik/react-js.git
git checkout formularios
Manejo de formularios en React
El comportamiento de formularios en React es un poco diferente a otros elementos dentro del DOM que crea la librería de React, y esto se debe a que los formularios por si mismos almacenan un cierto tipo de estado.
Esto lo podemos ver claramente cuando utilizamos el tag form en HTML el cual tiene uno o mas inputs dentro de su estructura.
Cada input es capaz de almacenar información, por ejemplo, el name o el value, y después, recuperar el value a través de un identificador como el name para enviarlo al servidor a través de una API u otro medio de comunicación que tengamos con nuestro servidor.
Componentes controlados y no controlados
En su forma más básica los inputs dentro de un formulario los podemos manejar en una forma:
- Controlada
- Y no controlada
Inputs no controlados
Los input no controlados son una forma en que podemos manipular los componentes, esto quiere decir, que No vamos a utilizar el state de React para obtener o modificar los valores y propiedades de un form.
Entonces, para utilizar input no controlados lo podemos hacer utilizando:
- La refs en React
- O por eventos, tal como lo hace el evento submit en un tag form
Manejo de Inputs a través de Refs
Esto lo hemos visto en un capítulo anterior y solo debemos crear un referencia y a partir de ello obtener el value del input, por ejemplo:
class Componente extends React.Component{
constructor(props){
super(props);
this.nombre = React.createRef();
this.correo = React.createRef();
}
//Inputs no controlados, obteniendo datos a través de Refs
clicRefs(evento){
evento.preventDefault();
console.log(this.nombre.current.value);
console.log(this.correo.current.value);
}
render(){
return(
<form>
<h1>{"Formularios EWebik"}</h1>
<input type="text" refs={this.nombre} placeholder="Nombre" />
<input type="text" refs={this.correo} placeholder="Correo" />
<button onClick={this.clicRefs.bind(this)}>
Enviar
</button>
</form>
)
}
}
El código anterior es muy similar a como lo manejamos en HTML, es una buena opción cuando tienes pocos input y no tienes que hacer grandes validaciones.
Gracias por tu calificación
(2)
Manejo de Inputs a través de submit
La forma clásica del manejo de formularios es recuperar la información de cada input cuando se dispara el evento submit, esto seguramente lo has hecho en JavaScript en un login o algo por el estilo, en React lo podemos hacer de la siguiente manera.
class Componente extends React.Component{
//Inputs no controlados, obteniendo datos a través del evento submit
clicEventos(evento){
evento.preventDefault();
console.log(evento.target[0].value);
console.log(evento.target[1].value);
}
render(){
return(
<form onSubmit={this.clicEventos}>
<h1>{"Formularios EWebik"}</h1>
<input type="text" placeholder="Nombre" />
<input type="text" placeholder="Correo" />
<button>
Enviar
</button>
</form>
)
}
}
Al igual que en el caso anterior es útil cuando no se tiene que hacer validaciones complejas y son pocos inputs.
Ventaja y desventaja de utilizar componentes no controlados
- Ventaja, el código es menos complejo y muy fácil de escribir.
- Desventaja, la validación del valor de cada input por lo regular se hace hasta que el usuario lanza el evento submit.
Como puedes ver esta forma de manejo es algo rudimentaria pero es importante que la conozcas, dado que en alguna aplicación quizá te sea útil. Ahora pasemos a los input controlados que es lo que vas a utilizar prácticamente siempre.
Inputs controlados
Utilizar los input de una forma controlada es la forma recomendable al utilizar React, ya que que te permitirá reutilizar mucho código y podrás adherir muchas funcionalidades a tus componentes, por ejemplo, desarrollemos el siguiente formulario aplicando componentes controlados.
Para pode desarrollar este formulario a través de componentes controlados, debemos crear cada uno de los componentes con su state particular.
Creando input tipo text controlado
Este componente utiliza el state para almacenar el valor del input y un estado de error que indicará si el usuario esta introduciendo un dato valido, en formulario de ejemplo lo utilizamos para validar que lo que ingresa es un nombre y un correo, si el código te resulta algo complicado, por favor, mira el vídeo.
class InputText extends React.Component{
constructor(props){
super(props);
this.actualizarState = this.actualizarState.bind(this);
this.state = {
value:"",
error:false,
mensajeError:""
};
}
actualizarState(e){
const {name, value} = e.target;
//console.log(name)
//console.log(value)
console.log(this.props.validacion(value));
if(this.props.validacion(value)){
this.setState({
value,
error:false,
mensajeError:""
});
this.props.actualizarState({
name,value,error:false
});
}else{
this.setState({
value,
error:true,
mensajeError:this.props.mensajeError
});
this.props.actualizarState({
name,value,error:true
});
}
}
render(){
return(
<div className="componente-input">
<label htmlFor={"id-"+this.props.name}>{this.props.label}</label>
<input
id={"id-"+this.props.name}
type="text"
name={this.props.name}
placeholder={this.props.placeholder}
className={this.state.error ? "border-error":""}
onChange={this.actualizarState}/>
{
this.state.error ? (
<p className="componente-input-error">{this.state.mensajeError}</p>
):("")
}
</div>
)
}
}
Si el usuario ingresa un dato no valido, se mostrara un párrafo en color rojo que le indica al usuario que el dato no es el correcto y debe corregir.
Gracias por tu calificación
(2)
Creando input tipo Checkbox controlado
Este componente es un poco más simple ya que solo cuenta con dos estados posibles.
class InputCheckbox extends React.Component{
constructor(props){
super(props)
this.actualizarState = this.actualizarState.bind(this);
this.state={activo:false};
}
actualizarState(e){
const {name, checked} = e.target;
this.setState({activo:checked});
this.props.actualizarState({
name,value:checked,error:false
})
}
render(){
return(
<div>
<input
id={"id-"+this.props.name}
type="checkbox"
name={this.props.name}
checked={this.state.activo}
onChange={this.actualizarState}/>
<label htmlFor={"id-"+this.props.name}>{this.props.label}</label>
</div>
)
}
}
Creando input tipo select controlado
Ahora veremos como agregar una lista desplegable de opciones en nuestro formulario, el siguiente checkbox nos permite agregar una lista con las opciones que nosotros deseemos, por el momento solo agregamos dos casos validos y uno no valido, por lo que se valida que el value de la opción no sea un carácter vacío.
class InputSelect extends React.Component{
constructor(props){
super(props)
this.actualizarState = this.actualizarState.bind(this);
this.state={activo:""};
}
actualizarState(e){
const {name, value} = e.target;
this.setState({value});
this.props.actualizarState({
name,value,error: value == "" ? true:false
})
}
render(){
return(
<div className="componente-input">
<label htmlFor={"id-"+this.props.name}>{this.props.label}</label>
<select
id={"id-"+this.props.name}
name={this.props.name}
onChange={this.actualizarState}>
{
this.props.opciones.map((opcion,index)=>(
<option hey={index} value={opcion.value}>{opcion.texto}</option>
))
}
</select>
</div>
)
}
}
Creando un form con inputs controlados
Ahora que tenemos nuestros componentes básicos necesitamos crear nuestro formulario agregando cada uno de nuestros inputs controlados y lo haremos de la siguiente manera.
Gracias por tu calificación
(2)
class Componente extends React.Component{
constructor(props){
super(props);
this.submit = this.submit.bind(this);
this.actualizarState = this.actualizarState.bind(this);
this.state = {
nombre:{
value:"",
error:true
},
correo:{
value:"",
error:true
},
prioridad:{
value:false,
error:true
},
opciones:{
value:"",
error:true
}
}
}
actualizarState(input){
this.setState({
...this.state,
[input.name]:{
value:input.value,
error:input.error
}
}, ()=>{console.log(this.state);});
}
submit(e){
e.preventDefault();
console.log(this.state)
}
render(){
return(
<form onSubmit={this.submit}>
<h1>{"Formularios EWebik"}</h1>
<InputText
label="Nombre"
name="nombre"
placeholder="Nombre"
validacion={esNombre}
mensajeError="Se esperaban letras"
actualizarState={this.actualizarState} />
<InputText
label="Correo"
name="correo"
placeholder="Correo"
validacion={esCorreo}
mensajeError="Correo no valido"
actualizarState={this.actualizarState} />
<InputCheckbox
name="prioridad"
label="Prioridad"
actualizarState={this.actualizarState} />
<InputSelect
name="opciones"
label="Elige una opción:"
actualizarState={this.actualizarState}
opciones={[
{value:"", texto:"Seleccione un opción..."},
{value:"1", texto:"Página web"},
{value:"2", texto:"Aplicación móvil"}
]} />
<button
disabled={this.state.nombre.error ||
this.state.correo.error ||
this.state.opciones.error}
type="submit"
className={this.state.nombre.error ||
this.state.correo.error ||
this.state.opciones.error
?
"button-disable":"button"}>
Enviar
</button>
</form>
)
}
}
ReactDOM.render(
<Componente/>,
document.getElementById('root')
);
En este componente:
- Llamamos cada input controlado y lo inicializamos
- Creamos una validación para cada InputText
- Tenemos un state que almacena el valor de cada input junto con su estado de error
- Si un input tiene un error, el botón de envió se mantiene disabled para no enviar datos erroneos
- Declaramos un función actualizarState la cual recibirá el valor de cada componente del formulario y actualizará el state
- Por ultimo tenemos una función submit, donde tenemos datos validos y podemos enviarlos a una API o a otro lugar según el tipo de tu aplicación.
Finalmente te dejo el código CSS del formulario, realmente es muy básico y no utilice una paleta de colores, así que puedes modificarlo y mejorarlo antes de utilizarlo en tu proyecto.
.componente-input{
display: flex;
flex-direction: column;
margin: 10px 0px;
}
.componente-input label{
margin: 5px 0px;
font-size: 18px;
}
.componente-input input
,.componente-input select{
height: 45px;
font-size: 18px;
}
.componente-input-error{
color: red;
font-size: 16px;
}
.border-error{
border: 1px solid red;
}
.button{
background-color: royalblue;
padding: 10px;
font-weight: bold;
font-size: 18px;
color: #fff;
}
.button-disable{
background-color: darkgray;
padding: 10px;
font-weight: bold;
font-size: 18px;
color: #fff;
}
Espero que esta clase te haya sido de gran ayuda, si te ha gustado suscríbete a mi canal de YouTube y comparte para que llegue a más personas que se les dificulta adquirir un corso de React y realmente tengan ganas de aprender, nos vemos en el próximo post.
Gracias por tu calificación
(2)
🧐 Autoevaluación: Formularios en React
¿Qué son los input no controlados?
¿Qué son los input controlados?
Juan Carlos García
Desarrollador de software / SEO
Durante años he desarrollado plataformas dedicadas al rastreo satelital y varios sitios web que se encuentran en la primera página de Google, y hoy quiero compartir contigo lo que se en tecnologías como: Node JS, PHP, C# y Bases de datos.
Si quieres apoyarme sígueme en mis redes sociales y suscríbete a mi canal de YouTube.