TechLead

Formularios y Componentes Controlados

Manejar inputs de formularios y componentes controlados

Formularios en React

En React, los elementos de formulario funcionan diferente a otros elementos DOM. Los formularios React tipicamente usan "componentes controlados" donde el estado de React es la "unica fuente de verdad".

Componentes Controlados

import { useState } from 'react';

function FormularioControlado() {
  const [nombre, setNombre] = useState('');

  const handleChange = (e) => {
    setNombre(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Nombre enviado:', nombre);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Nombre:
        <input
          type="text"
          value={nombre}
          onChange={handleChange}
        />
      </label>
      <button type="submit">Enviar</button>
    </form>
  );
}

Multiples Inputs

function FormularioRegistro() {
  const [formData, setFormData] = useState({
    nombre: '',
    email: '',
    password: ''
  });

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({
      ...prev,
      [name]: value
    }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Form data:', formData);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        name="nombre"
        value={formData.nombre}
        onChange={handleChange}
        placeholder="Nombre"
      />
      <input
        name="email"
        type="email"
        value={formData.email}
        onChange={handleChange}
        placeholder="Email"
      />
      <input
        name="password"
        type="password"
        value={formData.password}
        onChange={handleChange}
        placeholder="Contrasena"
      />
      <button type="submit">Registrar</button>
    </form>
  );
}

Diferentes Tipos de Input

function FormularioCompleto() {
  const [form, setForm] = useState({
    texto: '',
    select: '',
    checkbox: false,
    radio: '',
    textarea: ''
  });

  const handleChange = (e) => {
    const { name, value, type, checked } = e.target;
    setForm(prev => ({
      ...prev,
      [name]: type === 'checkbox' ? checked : value
    }));
  };

  return (
    <form>
      {/* Input de texto */}
      <input name="texto" value={form.texto} onChange={handleChange} />

      {/* Select */}
      <select name="select" value={form.select} onChange={handleChange}>
        <option value="">Selecciona...</option>
        <option value="opcion1">Opcion 1</option>
        <option value="opcion2">Opcion 2</option>
      </select>

      {/* Checkbox */}
      <input
        type="checkbox"
        name="checkbox"
        checked={form.checkbox}
        onChange={handleChange}
      />

      {/* Radio */}
      <input
        type="radio"
        name="radio"
        value="a"
        checked={form.radio === 'a'}
        onChange={handleChange}
      /> A
      <input
        type="radio"
        name="radio"
        value="b"
        checked={form.radio === 'b'}
        onChange={handleChange}
      /> B

      {/* Textarea */}
      <textarea name="textarea" value={form.textarea} onChange={handleChange} />
    </form>
  );
}

Validacion de Formularios

function FormularioConValidacion() {
  const [email, setEmail] = useState('');
  const [error, setError] = useState('');

  const validarEmail = (valor) => {
    if (!valor) {
      return 'El email es requerido';
    }
    if (!/\S+@\S+\.\S+/.test(valor)) {
      return 'Email invalido';
    }
    return '';
  };

  const handleChange = (e) => {
    const valor = e.target.value;
    setEmail(valor);
    setError(validarEmail(valor));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    const errorValidacion = validarEmail(email);
    if (errorValidacion) {
      setError(errorValidacion);
      return;
    }
    console.log('Enviando:', email);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={handleChange}
        className={error ? 'error' : ''}
      />
      {error && <span className="mensaje-error">{error}</span>}
      <button type="submit">Enviar</button>
    </form>
  );
}

Componentes Controlados vs No Controlados

  • Controlados: El estado de React controla el valor del input
  • No Controlados: El DOM maneja el estado del input (usando refs)
  • Recomendacion: Usa componentes controlados para la mayoria de casos