11.3-formulario

 

Tutorial: Formularios en React - Manejo de Inputs

馃摑 Conceptos B谩sicos de Formularios en React

En React, los formularios se manejan de forma diferente a HTML puro. React controla los datos del formulario a trav茅s del estado (state).

馃幆 Ejemplo 1: Input B谩sico Controlado

jsx

import React, { useState } from 'react';


function FormularioBasico() {

  // 1. Creamos el estado para almacenar el valor del input

  const [texto, setTexto] = useState('');


  // 2. Funci贸n para manejar los cambios en el input

  const manejarCambio = (evento) => {

    // event.target.value contiene el nuevo valor

    setTexto(evento.target.value);

  };


  // 3. Funci贸n para manejar el env铆o del formulario

  const manejarEnvio = (evento) => {

    evento.preventDefault(); // Evita que la p谩gina se recargue

    alert(`Texto enviado: ${texto}`);

    setTexto(''); // Limpiamos el input despu茅s de enviar

  };


  return (

    <form onSubmit={manejarEnvio}>

      <label htmlFor="miInput">

        Escribe algo:

      </label>

      

      {/* Input controlado por React */}

      <input

        id="miInput"

        type="text"

        value={texto} // El valor viene del estado

        onChange={manejarCambio} // Actualiza el estado cuando cambia

        placeholder="Escribe aqu铆..."

      />

      

      <button type="submit">

        Enviar

      </button>

      

      {/* Mostramos el valor actual en tiempo real */}

      <p>Texto actual: {texto}</p>

    </form>

  );

}


export default FormularioBasico;

馃攳 Explicaci贸n Paso a Paso

Paso 1: Crear el Estado

javascript

const [texto, setTexto] = useState('');

  • texto: Variable que almacena el valor actual (string vac铆o inicialmente)

  • setTexto: Funci贸n para actualizar el valor

Paso 2: Input Controlado

jsx

<input

  value={texto}

  onChange={manejarCambio}

/>

  • value={texto}: El input muestra lo que hay en el estado

  • onChange={manejarCambio}: Cuando el usuario escribe, se ejecuta manejarCambio

Paso 3: Funci贸n de Cambio

javascript

const manejarCambio = (evento) => {

  setTexto(evento.target.value);

};

  • evento.target.value: Contiene el nuevo texto escrito por el usuario

  • setTexto(): Actualiza el estado con el nuevo valor

馃搳 Ejemplo 2: Input con Validaci贸n

jsx

import React, { useState } from 'react';


function FormularioConValidacion() {

  const [email, setEmail] = useState('');

  const [error, setError] = useState('');


  const manejarCambioEmail = (e) => {

    const valor = e.target.value;

    setEmail(valor);

    

    // Validaci贸n simple de email

    if (valor && !valor.includes('@')) {

      setError('Debe contener @');

    } else {

      setError('');

    }

  };


  const manejarEnvio = (e) => {

    e.preventDefault();

    if (!error && email) {

      alert(`Email v谩lido: ${email}`);

      setEmail('');

    } else {

      alert('Corrige el email primero');

    }

  };


  return (

    <form onSubmit={manejarEnvio} style={{ padding: '20px' }}>

      <h3>Registro de Email</h3>

      

      <div>

        <label>

          Tu email:

          <input

            type="email"

            value={email}

            onChange={manejarCambioEmail}

            placeholder="ejemplo@correo.com"

            style={{

              marginLeft: '10px',

              padding: '8px',

              border: error ? '2px solid red' : '1px solid gray'

            }}

          />

        </label>

      </div>

      

      {/* Mostrar error si existe */}

      {error && <p style={{ color: 'red' }}>{error}</p>}

      

      {/* Mostrar el email en tiempo real */}

      <p>Email ingresado: {email || '(vac铆o)'}</p>

      

      <button 

        type="submit"

        disabled={!!error || !email}

        style={{

          padding: '10px 20px',

          backgroundColor: error || !email ? '#ccc' : '#4CAF50',

          color: 'white',

          border: 'none',

          cursor: error || !email ? 'not-allowed' : 'pointer'

        }}

      >

        Registrarse

      </button>

    </form>

  );

}


export default FormularioConValidacion;

馃帹 Ejemplo 3: Input con Caracter铆sticas Adicionales

jsx

import React, { useState } from 'react';


function InputAvanzado() {

  const [usuario, setUsuario] = useState({

    nombre: '',

    contrasena: '',

    mostrarPassword: false

  });


  const manejarCambio = (e) => {

    const { name, value } = e.target;

    setUsuario(prev => ({

      ...prev,

      [name]: value

    }));

  };


  const toggleMostrarPassword = () => {

    setUsuario(prev => ({

      ...prev,

      mostrarPassword: !prev.mostrarPassword

    }));

  };


  const manejarEnvio = (e) => {

    e.preventDefault();

    console.log('Usuario:', usuario);

    alert(`Nombre: ${usuario.nombre}\nContrase帽a oculta por seguridad`);

  };


  return (

    <form onSubmit={manejarEnvio} style={styles.formulario}>

      <h2>Registro de Usuario</h2>

      

      {/* Input para nombre */}

      <div style={styles.grupo}>

        <label style={styles.label}>

          Nombre completo:

        </label>

        <input

          name="nombre"

          type="text"

          value={usuario.nombre}

          onChange={manejarCambio}

          placeholder="Tu nombre"

          style={styles.input}

          maxLength={50}

        />

        <small style={styles.contador}>

          {usuario.nombre.length}/50 caracteres

        </small>

      </div>

      

      {/* Input para contrase帽a */}

      <div style={styles.grupo}>

        <label style={styles.label}>

          Contrase帽a:

        </label>

        <div style={{ display: 'flex', alignItems: 'center' }}>

          <input

            name="contrasena"

            type={usuario.mostrarPassword ? "text" : "password"}

            value={usuario.contrasena}

            onChange={manejarCambio}

            placeholder="Tu contrase帽a"

            style={styles.input}

          />

          <button

            type="button"

            onClick={toggleMostrarPassword}

            style={styles.botonToggle}

          >

            {usuario.mostrarPassword ? "馃檲" : "馃憗️"}

          </button>

        </div>

      </div>

      

      {/* Bot贸n de env铆o */}

      <button 

        type="submit"

        style={styles.botonEnviar}

        disabled={!usuario.nombre || !usuario.contrasena}

      >

        Crear cuenta

      </button>

      

      {/* Vista previa */}

      <div style={styles.vistaPrevia}>

        <h4>Vista previa:</h4>

        <p><strong>Nombre:</strong> {usuario.nombre || '(sin nombre)'}</p>

        <p><strong>Contrase帽a:</strong> {usuario.contrasena ? '••••••' : '(sin contrase帽a)'}</p>

      </div>

    </form>

  );

}


// Estilos en objeto JavaScript

const styles = {

  formulario: {

    maxWidth: '400px',

    margin: '0 auto',

    padding: '20px',

    border: '1px solid #ddd',

    borderRadius: '8px',

    backgroundColor: '#f9f9f9'

  },

  grupo: {

    marginBottom: '20px'

  },

  label: {

    display: 'block',

    marginBottom: '5px',

    fontWeight: 'bold'

  },

  input: {

    width: '100%',

    padding: '10px',

    border: '1px solid #ccc',

    borderRadius: '4px',

    fontSize: '16px'

  },

  contador: {

    display: 'block',

    textAlign: 'right',

    color: '#666',

    marginTop: '5px'

  },

  botonToggle: {

    marginLeft: '10px',

    padding: '10px',

    backgroundColor: '#007bff',

    color: 'white',

    border: 'none',

    borderRadius: '4px',

    cursor: 'pointer'

  },

  botonEnviar: {

    width: '100%',

    padding: '12px',

    backgroundColor: '#28a745',

    color: 'white',

    border: 'none',

    borderRadius: '4px',

    fontSize: '16px',

    cursor: 'pointer',

    opacity: 1

  },

  vistaPrevia: {

    marginTop: '20px',

    padding: '15px',

    backgroundColor: '#e9ecef',

    borderRadius: '4px'

  }

};


export default InputAvanzado;

馃摎 Resumen de Conceptos Clave

1. Componente Controlado vs No Controlado

  • Controlado: React maneja el valor (recomendado)

  • jsx

  • <input value={estado} onChange={manejarCambio} />

  • No controlado: El DOM maneja el valor

  • jsx

  • <input defaultValue="valor inicial" />

2. Flujo de Datos

text

Usuario escribe → evento onChange → actualiza estado → se rerenderiza → input muestra nuevo valor

3. Eventos Principales

  • onChange: Cuando el valor cambia

  • onSubmit: Cuando se env铆a el formulario

  • onFocus: Cuando el input recibe foco

  • onBlur: Cuando el input pierde foco

4. Tipos de Input Comunes

jsx

<input type="text" />     // Texto normal

<input type="email" />    // Email

<input type="password" /> // Contrase帽a

<input type="number" />   // N煤meros

<input type="date" />     // Fecha

<textarea />              // Texto multil铆nea

馃殌 Ejemplo Final: Todo en Uno

jsx

import React, { useState } from 'react';


function FormularioTodoUno() {

  const [input, setInput] = useState('');

  

  const manejarCambio = (e) => setInput(e.target.value);

  

  const manejarEnvio = (e) => {

    e.preventDefault();

    alert(`Texto guardado: ${input}`);

    setInput('');

  };

  

  return (

    <div style={{ textAlign: 'center', marginTop: '50px' }}>

      <h1>馃枈️ Formulario Simple en React</h1>

      

      <form onSubmit={manejarEnvio}>

        <input

          type="text"

          value={input}

          onChange={manejarCambio}

          placeholder="Escribe algo incre铆ble..."

          style={{

            padding: '15px',

            fontSize: '18px',

            width: '300px',

            marginBottom: '20px'

          }}

        />

        <br />

        <button

          type="submit"

          style={{

            padding: '15px 30px',

            fontSize: '16px',

            backgroundColor: '#2196F3',

            color: 'white',

            border: 'none',

            borderRadius: '5px',

            cursor: 'pointer'

          }}

        >

          Guardar ✨

        </button>

      </form>

      

      <div style={{ marginTop: '30px' }}>

        <h3>馃幆 Lo que escribes aparece aqu铆:</h3>

        <div style={{

          padding: '20px',

          backgroundColor: '#e3f2fd',

          borderRadius: '5px',

          minHeight: '50px',

          fontSize: '20px',

          fontWeight: 'bold'

        }}>

          {input || '¡Empieza a escribir arriba!'}

        </div>

      </div>

    </div>

  );

}


export default FormularioTodoUno;

✅ Mejores Pr谩cticas

  1. Siempre usar preventDefault() en el submit

  2. Validar datos antes de enviar

  3. Dar feedback visual al usuario

  4. Usar htmlFor y id para accesibilidad

  5. Manejar estados de carga y error

馃帗 Ejercicio para Practicar

Crea un input donde:

  1. Cuente las palabras escritas

  2. Cambie de color cuando tenga m谩s de 10 caracteres

  3. Muestre un mensaje especial cuando diga "React"

¡Ahora tienes las bases para manejar formularios en React!


Comentarios

Entradas m谩s populares de este blog

9.3-Tutorial de Componentes React con Props -SSS

9.6-Ciclo de Vida de un Componente React

9-Componentes en React-estado