Fortgeschritten222025-01-15

React Forms - Input Handling & Validation

Lerne Forms in React zu bauen. Controlled vs Uncontrolled Components, Validation, Multi-Input Forms und Form Libraries.

#react#forms#validation#controlled-components

React Forms

Forms in React erfordern spezielles Handling. Controlled Components sind der empfohlene Weg!

Controlled vs Uncontrolled

Unterschied verstehen
// ❌ Uncontrolled - React kennt den Wert nicht
function UncontrolledForm() {
  const inputRef = useRef()

  const handleSubmit = (e) => {
    e.preventDefault()
    console.log(inputRef.current.value) // Wert aus DOM holen
  }

  return (
    <form onSubmit={handleSubmit}>
      <input ref={inputRef} />
    </form>
  )
}

// ✅ Controlled - React kontrolliert den Wert
function ControlledForm() {
  const [value, setValue] = useState('')

  const handleSubmit = (e) => {
    e.preventDefault()
    console.log(value) // Wert aus State
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
    </form>
  )
}

Simple Form

Login Form
function LoginForm() {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [error, setError] = useState('')

  const handleSubmit = async (e) => {
    e.preventDefault()
    setError('')

    // Validation
    if (!email || !password) {
      setError('Bitte alle Felder ausfüllen')
      return
    }

    // Submit
    try {
      await login(email, password)
    } catch (err) {
      setError(err.message)
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      {error && <div className="error">{error}</div>}

      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Email"
        required
      />

      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="Password"
        required
      />

      <button type="submit">Login</button>
    </form>
  )
}

Multi-Input Form

Form mit Object State
function RegistrationForm() {
  const [formData, setFormData] = useState({
    username: '',
    email: '',
    password: '',
    confirmPassword: '',
    agreeToTerms: false
  })

  const handleChange = (e) => {
    const { name, value, type, checked } = e.target

    setFormData(prev => ({
      ...prev,
      [name]: type === 'checkbox' ? checked : value
    }))
  }

  const handleSubmit = (e) => {
    e.preventDefault()

    // Validation
    if (formData.password !== formData.confirmPassword) {
      alert('Passwörter stimmen nicht überein!')
      return
    }

    if (!formData.agreeToTerms) {
      alert('Bitte AGB akzeptieren')
      return
    }

    console.log('Submit:', formData)
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        name="username"
        value={formData.username}
        onChange={handleChange}
        placeholder="Username"
      />

      <input
        name="email"
        type="email"
        value={formData.email}
        onChange={handleChange}
        placeholder="Email"
      />

      <input
        name="password"
        type="password"
        value={formData.password}
        onChange={handleChange}
        placeholder="Password"
      />

      <input
        name="confirmPassword"
        type="password"
        value={formData.confirmPassword}
        onChange={handleChange}
        placeholder="Confirm Password"
      />

      <label>
        <input
          name="agreeToTerms"
          type="checkbox"
          checked={formData.agreeToTerms}
          onChange={handleChange}
        />
        Ich akzeptiere die AGB
      </label>

      <button type="submit">Registrieren</button>
    </form>
  )
}

Validation

Live Validation
function ValidatedForm() {
  const [email, setEmail] = useState('')
  const [errors, setErrors] = useState({})

  const validateEmail = (value) => {
    const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
    return regex.test(value)
  }

  const handleEmailChange = (e) => {
    const value = e.target.value
    setEmail(value)

    // Live Validation
    if (value && !validateEmail(value)) {
      setErrors(prev => ({
        ...prev,
        email: 'Ungültige Email-Adresse'
      }))
    } else {
      setErrors(prev => {
        const newErrors = { ...prev }
        delete newErrors.email
        return newErrors
      })
    }
  }

  return (
    <div>
      <input
        type="email"
        value={email}
        onChange={handleEmailChange}
        className={errors.email ? 'error' : ''}
      />
      {errors.email && (
        <span className="error-message">{errors.email}</span>
      )}
    </div>
  )
}

Select & Radio

Andere Input Types
function FormInputTypes() {
  const [country, setCountry] = useState('de')
  const [gender, setGender] = useState('other')

  return (
    <form>
      {/* Select Dropdown */}
      <select
        value={country}
        onChange={(e) => setCountry(e.target.value)}
      >
        <option value="de">Deutschland</option>
        <option value="at">Österreich</option>
        <option value="ch">Schweiz</option>
      </select>

      {/* Radio Buttons */}
      <div>
        <label>
          <input
            type="radio"
            value="male"
            checked={gender === 'male'}
            onChange={(e) => setGender(e.target.value)}
          />
          Männlich
        </label>

        <label>
          <input
            type="radio"
            value="female"
            checked={gender === 'female'}
            onChange={(e) => setGender(e.target.value)}
          />
          Weiblich
        </label>

        <label>
          <input
            type="radio"
            value="other"
            checked={gender === 'other'}
            onChange={(e) => setGender(e.target.value)}
          />
          Divers
        </label>
      </div>
    </form>
  )
}

Form Libraries

React Hook Form (empfohlen)
import { useForm } from 'react-hook-form'

function HookFormExample() {
  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm()

  const onSubmit = (data) => {
    console.log(data)
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        {...register('email', {
          required: 'Email ist erforderlich',
          pattern: {
            value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
            message: 'Ungültige Email'
          }
        })}
      />
      {errors.email && <span>{errors.email.message}</span>}

      <input
        {...register('password', {
          required: 'Password ist erforderlich',
          minLength: {
            value: 8,
            message: 'Mindestens 8 Zeichen'
          }
        })}
        type="password"
      />
      {errors.password && <span>{errors.password.message}</span>}

      <button type="submit">Submit</button>
    </form>
  )
}

📝 Quiz

Was ist der Hauptvorteil von Controlled Components?

🎯

Zusammenfassung

Du hast gelernt:

  • ✅ Controlled Components (value + onChange)
  • ✅ Uncontrolled Components (refs)
  • ✅ Multi-Input Forms mit Object State
  • ✅ Form Validation
  • ✅ Select, Radio, Checkbox
  • ✅ Form Libraries (React Hook Form)

Best Practices:

  • Immer Controlled Components nutzen
  • e.preventDefault() bei onSubmit
  • Validation clientseitig UND serverseitig
  • Error Messages für User anzeigen
  • Loading States während Submit
  • Form Libraries für komplexe Forms
ReactLektion 6 von 10
60% abgeschlossen

Artikel bewerten

0.0 (0 Bewertungen)

Bitte einloggen um zu bewerten