# Formularios
Documentación oficial: https://es.reactjs.org/docs/forms.html
import React, {Fragment, useState} from 'react';
const Formulario = () => {
const [datos, setDatos] = useState({
nombre: '',
apellido: ''
})
const handleInputChange = (event) => {
// console.log(event.target.name)
// console.log(event.target.value)
setDatos({
...datos,
[event.target.name] : event.target.value
})
}
const enviarDatos = (event) => {
event.preventDefault()
console.log('enviando datos...' + datos.nombre + ' ' + datos.apellido)
}
return (
<Fragment>
<h1>Formulario</h1>
<form className="row" onSubmit={enviarDatos}>
<div className="col-md-3">
<input type="text" placeholder="Nombre" className="form-control" onChange={handleInputChange} name="nombre"></input>
</div>
<div className="col-md-3">
<input type="text" placeholder="Apellido" className="form-control" onChange={handleInputChange} name="apellido"></input>
</div>
<button type="submit" className="btn btn-primary">Enviar</button>
</form>
<ul>
<li>{datos.nombre}</li>
<li>{datos.apellido}</li>
</ul>
</Fragment>
);
}
export default Formulario;
# State
Los datos que utilizaremos en nuestro formulario:
const [datos, setDatos] = useState({
nombre: '',
apellido: ''
})
# Form
Utilizando clases de Bootstrap para que se vea más bonito, atributos y eventos para que la magia funcione:
<form className="row" onSubmit={enviarDatos}>
<div className="col-md-3">
<input
type="text"
placeholder="Nombre"
className="form-control"
onChange={handleInputChange}
name="nombre" />
</div>
<div className="col-md-3">
<input
type="text"
placeholder="Apellido"
className="form-control"
onChange={handleInputChange}
name="apellido" />
</div>
<button type="submit" className="btn btn-primary">Enviar</button>
</form>
# Evento onChange
Estará al pendiente de los cambios que se registren en nuestro input, por lo tanto creamos una función para modificar nuestro state.
const handleInputChange = (event) => {
// console.log(event.target.name)
// console.log(event.target.value)
setDatos({
...datos,
[event.target.name] : event.target.value
})
}
A partir de ECMAScript 2015, la sintaxis del inicializador de objetos también admite nombres de propiedades calculados. Eso le permite poner una expresión entre paréntesis [], que se calculará y usará como el nombre de la propiedad. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names
# onSubmit
Ahora con los datos ya ingresados podemos utilizar el evento onSubmit para procesar el formulario:
<form onSubmit={enviarDatos}>
const enviarDatos = (event) => {
event.preventDefault()
console.log('enviando datos...' + datos.nombre + ' ' + datos.apellido)
}
# React Hook Form
https://react-hook-form.com/get-started
# Instalación
npm install react-hook-form
# Utilización
import React, {Fragment} from 'react'
import { useForm } from 'react-hook-form'
const HookForm = () => {
const {register, errors, handleSubmit} = useForm();
const onSubmit = (data) => {
console.log(data)
}
return (
<Fragment>
<h2>Hooks Forms</h2>
<form onSubmit={handleSubmit(onSubmit)}>
<input
placeholder="Ingrese nombre de usuario"
className="form-control mb-2"
name="usuario"
ref={register({
required: {
value: true,
message: 'Nombre es requerido'
},
maxLength: {
value: 5,
message: 'No más de 5 carácteres!'
},
minLength: {
value: 2,
message: 'Mínimo 2 carácteres'
}
})}
></input>
<button type="submit" className="btn btn-primary">
Enviar
</button>
</form>
</Fragment>
);
}
export default HookForm;
# onSubmit
Uno de los conceptos clave en el formulario React Hook, es pasar su componente no controlado en el gancho. Esto hará que su valor esté disponible tanto para la validación como para el envío del formulario. register
const onSubmit = (data) => {
console.log(data)
}
// En el formulario
<form onSubmit={handleSubmit(onSubmit)}>
# Validación
Muy importante pasar el atributo "name" con clave única.
Pasamos ref con "register" y sus respectivas validaciones:
<input
placeholder="Ingrese nombre de usuario"
className="form-control mb-2"
name="usuario"
ref={
register({
required: {
value: true,
message: 'Nombre es requerido'
},
maxLength: {
value: 5,
message: 'No más de 5 carácteres!'
},
minLength: {
value: 2,
message: 'Mínimo 2 carácteres'
}
})
}
/>
# Errores
https://react-hook-form.com/advanced-usage#ErrorMessage
<span className="text-danger text-small d-block mb-2">
{errors.usuario && errors.usuario.message}
</span>
<span className="text-danger text-small d-block mb-2">
{errors?.email?.message}
</span>
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
# Limpiar campos (Reset)
https://codesandbox.io/s/jjm3wyqmjy
const onSubmit = (data, e) => {
console.log(data)
// limpiar campos
e.target.reset();
}
# Ejemplo #1
Puedes ver el siguiente video explicando el ejemplo a continuación...
import React, { Fragment, useState } from 'react';
import { useForm } from 'react-hook-form';
const FormCrud = () => {
const {register, errors, handleSubmit} = useForm();
const [entradas, setentradas] = useState([]);
const procesarFormulario = (data, e) => {
console.log(data);
setentradas([
...entradas,
data
])
// limpiar campos
e.target.reset();
}
return (
<Fragment>
<h1>FORM</h1>
<form onSubmit={handleSubmit(procesarFormulario)}>
<input
name="titulo"
ref={
register({
required: {value:true, message: 'Ingrese un nombre'}
})
}
className="form-control my-2"
placeholder="Ingrese título"
></input>
<span className="text-danger text-small d-block mb-2">
{errors?.titulo?.message}
</span>
<input
name="descripcion"
ref={
register({
required: {value:true, message: 'Ingrese descripción'}
})
}
className="form-control my-2"
placeholder="Ingrese descripción"
></input>
<span className="text-danger text-small d-block mb-2">
{errors?.descripcion?.message}
</span>
<button
type="submit"
className="btn btn-primary"
>
Agregar
</button>
</form>
<ul className="mt-2">
{
entradas.map((item, index) =>
<li key={index}>
{item.titulo} - {item.descripcion}
</li>
)
}
</ul>
</Fragment>
);
}
export default FormCrud;
# Ejemplo #2 setError y clearError
https://github.com/email2vimalraj/Bin2Dec/blob/master/src/index.js
import React, { Fragment, useState } from 'react';
import { useForm } from 'react-hook-form';
const Binary = () => {
const [Decimal, setDecimal] = useState('');
const {register, errors, handleSubmit, setError, clearError} = useForm();
const onSubmit = (data, e) => {
// console.log(data)
if (data.binario.match(/^[0-1]+$/g) === null) {
setError(
"binario",
"notMatch",
"Ingrese 0 o 1"
);
return
}else{
clearError("binario");
}
// Formula:
// input = 1 => output = 1 * (2^0) = 1
// input = 10 => output = (0 * (2^0)) + (1 * (2^1)) = 2
// So we reverse and iterate from the back
const reversedBinaryText = data.binario
.split('')
.map(Number) // Convert to a number from string
.reverse()
// Calculate the result by accumulating previous vaue
const result = reversedBinaryText.reduce(
(accumulator, currentValue, idx) =>
accumulator + currentValue * Math.pow(2, idx)
)
console.log(result)
setDecimal(result)
}
return (
<Fragment>
<h1>Calculadora Binaria</h1>
<form className="form-inline" onSubmit={handleSubmit(onSubmit)}>
<div className="form-group mb-2">
<input
name="binario"
className="form-control rounded-0"
placeholder="Ingrese 0 y 1"
ref={register(
{
required:{value: true, message: 'Campo obligatorio'}
}
)}
></input>
</div>
<div className="form-group mb-2">
<button className="btn btn-primary rounded-0">Transformar</button>
</div>
</form>
{errors.binario &&
<span className="text-danger text-small d-block mb-2">
{errors.binario.message}
</span>
}
<p>Resultado: {Decimal}</p>
</Fragment>
);
}
export default Binary;
← JSX Components →