Einfaches Form-Handling mit Formik in React
Formulare sind ein wesentlicher Bestandteil fast jeder Web-Anwendung. In dieser Anleitung lernen Sie, wie Sie mit Formik und Yup Formulare in React einfach erstellen können. Das Endresultat sollte wie folgt aussehen:

Inhaltsverzeichnis
Abschnitt betitelt „Inhaltsverzeichnis“- Einführung
- Projektvorbereitung
- Einfaches Login-Formular
- Validierung mit Yup
- Erweitertes Registrierungsformular
- Formular absenden
- Zusammenfassung
Einführung
Abschnitt betitelt „Einführung“Die manuelle Verwaltung von Formularzuständen in React ist kompliziert. Hier sind die häufigsten Probleme:
- Sie müssen den Zustand für jedes Eingabefeld separat verwalten
- Sie müssen die Eingaben auf Gültigkeit prüfen
- Sie müssen Fehlermeldungen anzeigen
- Sie müssen die Formulardaten beim Absenden sammeln
Formik löst diese Probleme für Sie:
- Es verwaltet alle Zustände automatisch
- Es vereinfacht die Validierung
- Es zeigt Fehlermeldungen an den richtigen Stellen
- Es sammelt alle Daten für Sie
Yup arbeitet mit Formik zusammen und macht die Validierung kinderleicht.
Projektvorbereitung
Abschnitt betitelt „Projektvorbereitung“Schritt 1: Projekt erstellen
Abschnitt betitelt „Schritt 1: Projekt erstellen“# Mit Vite ein neues React-Projekt erstellennpm create vite@latest mein-formular-projekt -- --template react
# Ins Projektverzeichnis wechselncd mein-formular-projektSchritt 2: Formik und Yup installieren
Abschnitt betitelt „Schritt 2: Formik und Yup installieren“npm install formik yupSchritt 3: Projektordner vorbereiten
Abschnitt betitelt „Schritt 3: Projektordner vorbereiten“mkdir -p src/componentsmkdir -p src/stylestouch src/components/LoginForm.jsxtouch src/components/RegistrationForm.jsxtouch src/styles/forms.cssEinfaches Login-Formular
Abschnitt betitelt „Einfaches Login-Formular“Schritt 4: Ihr erstes Formik-Formular erstellen
Abschnitt betitelt „Schritt 4: Ihr erstes Formik-Formular erstellen“Öffnen Sie src/components/LoginForm.jsx und fügen Sie diesen Code ein:
import React from 'react';import { Formik, Form, Field, ErrorMessage } from 'formik';import * as Yup from 'yup';import '../styles/forms.css';
// Validierungsregelnconst LoginSchema = Yup.object().shape({ email: Yup.string() .email('Ungültige E-Mail-Adresse') .required('E-Mail ist erforderlich'), password: Yup.string() .required('Passwort ist erforderlich'),});
function LoginForm() { return ( <div className="form-container"> <h2>Anmelden</h2>
<Formik // Anfangswerte der Felder initialValues={{ email: '', password: '' }} // Validierungsregeln validationSchema={LoginSchema} // Was passiert beim Absenden onSubmit={(values, { setSubmitting }) => { // Simulieren wir einen Server-Aufruf setTimeout(() => { alert('Sie haben folgende Daten gesendet: \n' + JSON.stringify(values, null, 2)); setSubmitting(false); }, 500); }} > {({ isSubmitting }) => ( <Form className="form"> {/* E-Mail Feld */} <div className="form-group"> <label htmlFor="email">E-Mail</label> <Field type="email" name="email" id="email" className="form-control" placeholder="ihre@email.de" /> {/* Fehlermeldung für E-Mail */} <ErrorMessage name="email" component="div" className="error-message" /> </div>
{/* Passwort Feld */} <div className="form-group"> <label htmlFor="password">Passwort</label> <Field type="password" name="password" id="password" className="form-control" placeholder="Ihr Passwort" /> {/* Fehlermeldung für Passwort */} <ErrorMessage name="password" component="div" className="error-message" /> </div>
{/* Absende-Button */} <button type="submit" className="submit-button" disabled={isSubmitting} > {isSubmitting ? 'Wird angemeldet...' : 'Anmelden'} </button> </Form> )} </Formik> </div> );}
export default LoginForm;Schritt 5: Formular-Styling hinzufügen
Abschnitt betitelt „Schritt 5: Formular-Styling hinzufügen“Öffnen Sie src/styles/forms.css und fügen Sie dieses CSS ein:
.form-container { max-width: 400px; margin: 0 auto; padding: 20px; border: 1px solid #ddd; border-radius: 5px; background-color: #f9f9f9; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);}
h2 { text-align: center; margin-bottom: 20px; color: #333;}
.form { display: flex; flex-direction: column;}
.form-group { margin-bottom: 15px;}
label { display: block; margin-bottom: 5px; font-weight: bold; color: #555;}
.form-control { width: 100%; padding: 10px; font-size: 16px; border: 1px solid #ddd; border-radius: 4px;}
.form-control:focus { outline: none; border-color: #3498db; box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);}
.error-message { color: #e74c3c; font-size: 14px; margin-top: 5px;}
.submit-button { padding: 12px; background-color: #3498db; color: white; border: none; border-radius: 4px; font-size: 16px; cursor: pointer; margin-top: 10px;}
.submit-button:hover { background-color: #2980b9;}
.submit-button:disabled { background-color: #95a5a6; cursor: not-allowed;}
.checkbox-group { display: flex; align-items: center;}
.checkbox-group input[type="checkbox"] { margin-right: 10px;}
.form-row { display: flex; gap: 15px;}
.form-row .form-group { flex: 1;}
@media (max-width: 500px) { .form-row { flex-direction: column; gap: 0; }}Schritt 6: Login-Formular in der App anzeigen
Abschnitt betitelt „Schritt 6: Login-Formular in der App anzeigen“Öffnen Sie src/App.jsx und ersetzen Sie den Inhalt mit diesem Code:
import React from 'react';import LoginForm from './components/LoginForm';import './App.css';
function App() { return ( <div className="app"> <header className="app-header"> <h1>Mein Formular-Projekt</h1> </header> <main> <LoginForm /> </main> </div> );}
export default App;Schritt 7: App-Styling aktualisieren
Abschnitt betitelt „Schritt 7: App-Styling aktualisieren“Öffnen Sie src/App.css und fügen Sie folgendes hinzu:
.app { padding: 20px; max-width: 800px; margin: 0 auto;}
.app-header { text-align: center; margin-bottom: 30px;}Schritt 8: App starten
Abschnitt betitelt „Schritt 8: App starten“Führen Sie diesen Befehl im Terminal aus:
npm run devÖffnen Sie Ihren Browser unter der angezeigten URL (meist http://localhost:5173).
Validierung mit Yup
Abschnitt betitelt „Validierung mit Yup“Schritt 9: Validierung verstehen
Abschnitt betitelt „Schritt 9: Validierung verstehen“Die Validierung im Login-Formular ist einfach. Schauen wir uns die Regeln an:
const LoginSchema = Yup.object().shape({ email: Yup.string() .email('Ungültige E-Mail-Adresse') // Muss eine gültige E-Mail sein .required('E-Mail ist erforderlich'), // Darf nicht leer sein password: Yup.string() .required('Passwort ist erforderlich'), // Darf nicht leer sein});Sie können mit Yup viele verschiedene Regeln erstellen:
.min(5, 'Zu kurz')- Mindestens 5 Zeichen.max(10, 'Zu lang')- Höchstens 10 Zeichen.email('Ungültige E-Mail')- Muss eine E-Mail sein.url('Ungültige URL')- Muss eine URL sein.matches(/regex/, 'Fehlermeldung')- Muss dem Muster entsprechen
Erweitertes Registrierungsformular
Abschnitt betitelt „Erweitertes Registrierungsformular“Schritt 10: Registrierungsformular erstellen
Abschnitt betitelt „Schritt 10: Registrierungsformular erstellen“Öffnen Sie src/components/RegistrationForm.jsx und fügen Sie diesen Code ein:
import React from 'react';import { Formik, Form, Field, ErrorMessage } from 'formik';import * as Yup from 'yup';import '../styles/forms.css';
// Umfangreichere Validierungsregelnconst RegistrationSchema = Yup.object().shape({ firstName: Yup.string() .min(2, 'Vorname muss mindestens 2 Zeichen lang sein') .required('Vorname ist erforderlich'), lastName: Yup.string() .min(2, 'Nachname muss mindestens 2 Zeichen lang sein') .required('Nachname ist erforderlich'), email: Yup.string() .email('Ungültige E-Mail-Adresse') .required('E-Mail ist erforderlich'), password: Yup.string() .min(8, 'Passwort muss mindestens 8 Zeichen lang sein') .required('Passwort ist erforderlich'), confirmPassword: Yup.string() .oneOf([Yup.ref('password')], 'Passwörter müssen übereinstimmen') .required('Passwort-Bestätigung ist erforderlich'), acceptTerms: Yup.boolean() .oneOf([true], 'Sie müssen die Nutzungsbedingungen akzeptieren')});
function RegistrationForm() { return ( <div className="form-container"> <h2>Registrieren</h2>
<Formik initialValues={{ firstName: '', lastName: '', email: '', password: '', confirmPassword: '', acceptTerms: false }} validationSchema={RegistrationSchema} onSubmit={(values, { setSubmitting, resetForm }) => { // Simuliere einen Server-Aufruf setTimeout(() => { alert('Registrierung erfolgreich!\n\n' + JSON.stringify(values, null, 2)); setSubmitting(false); resetForm(); }, 500); }} > {({ isSubmitting }) => ( <Form className="form"> {/* Vorname und Nachname nebeneinander */} <div className="form-row"> <div className="form-group"> <label htmlFor="firstName">Vorname</label> <Field type="text" name="firstName" id="firstName" className="form-control" /> <ErrorMessage name="firstName" component="div" className="error-message" /> </div>
<div className="form-group"> <label htmlFor="lastName">Nachname</label> <Field type="text" name="lastName" id="lastName" className="form-control" /> <ErrorMessage name="lastName" component="div" className="error-message" /> </div> </div>
{/* E-Mail */} <div className="form-group"> <label htmlFor="email">E-Mail</label> <Field type="email" name="email" id="email" className="form-control" /> <ErrorMessage name="email" component="div" className="error-message" /> </div>
{/* Passwort */} <div className="form-group"> <label htmlFor="password">Passwort</label> <Field type="password" name="password" id="password" className="form-control" /> <ErrorMessage name="password" component="div" className="error-message" /> </div>
{/* Passwort bestätigen */} <div className="form-group"> <label htmlFor="confirmPassword">Passwort bestätigen</label> <Field type="password" name="confirmPassword" id="confirmPassword" className="form-control" /> <ErrorMessage name="confirmPassword" component="div" className="error-message" /> </div>
{/* Nutzungsbedingungen */} <div className="form-group checkbox-group"> <label> <Field type="checkbox" name="acceptTerms" /> Ich akzeptiere die Nutzungsbedingungen </label> <ErrorMessage name="acceptTerms" component="div" className="error-message" /> </div>
{/* Registrierungs-Button */} <button type="submit" className="submit-button" disabled={isSubmitting} > {isSubmitting ? 'Wird registriert...' : 'Registrieren'} </button> </Form> )} </Formik> </div> );}
export default RegistrationForm;Schritt 11: Beide Formulare in der App anzeigen
Abschnitt betitelt „Schritt 11: Beide Formulare in der App anzeigen“Jetzt erweitern wir die App, um zwischen Login und Registrierung wechseln zu können:
import React, { useState } from 'react';import LoginForm from './components/LoginForm';import RegistrationForm from './components/RegistrationForm';import './App.css';
function App() { // State für das aktive Formular const [activeForm, setActiveForm] = useState('login');
return ( <div className="app"> <header className="app-header"> <h1>Mein Formular-Projekt</h1>
{/* Formular-Umschalter */} <div className="form-toggle"> <button className={activeForm === 'login' ? 'active' : ''} onClick={() => setActiveForm('login')} > Login </button> <button className={activeForm === 'register' ? 'active' : ''} onClick={() => setActiveForm('register')} > Registrieren </button> </div> </header>
<main> {/* Zeige das ausgewählte Formular */} {activeForm === 'login' ? <LoginForm /> : <RegistrationForm />} </main> </div> );}
export default App;Aktualisieren Sie src/App.css für die Umschaltknöpfe:
.app { padding: 20px; max-width: 800px; margin: 0 auto;}
.app-header { text-align: center; margin-bottom: 30px;}
.form-toggle { display: flex; justify-content: center; margin-top: 15px;}
.form-toggle button { padding: 8px 16px; background-color: #f1f1f1; border: 1px solid #ddd; cursor: pointer;}
.form-toggle button:first-child { border-radius: 4px 0 0 4px;}
.form-toggle button:last-child { border-radius: 0 4px 4px 0;}
.form-toggle button.active { background-color: #3498db; color: white; border-color: #3498db;}Formular absenden
Abschnitt betitelt „Formular absenden“Schritt 12: Was passiert beim Absenden?
Abschnitt betitelt „Schritt 12: Was passiert beim Absenden?“Bisher haben wir nur einen Alert angezeigt. In einer echten Anwendung würden Sie die Daten an einen Server senden. Hier ein einfaches Beispiel:
// In LoginForm.jsxonSubmit={async (values, { setSubmitting, setErrors }) => { try { // In einer echten App würden Sie hier einen API-Aufruf machen: // const response = await fetch('https://api.example.com/login', { // method: 'POST', // headers: { 'Content-Type': 'application/json' }, // body: JSON.stringify(values) // });
// Simuliere einen Server-Aufruf await new Promise(resolve => setTimeout(resolve, 1000));
console.log('Anmeldedaten:', values); alert('Anmeldung erfolgreich!');
// In einer echten App würden Sie hier den Benutzer einloggen // z.B. mit Cookies oder localStorage } catch (error) { // Bei einem Fehler zeige eine Fehlermeldung alert('Anmeldung fehlgeschlagen!'); } finally { // Immer ausführen, auch nach Fehler setSubmitting(false); }}}Zusammenfassung
Abschnitt betitelt „Zusammenfassung“Was haben Sie gelernt?
Abschnitt betitelt „Was haben Sie gelernt?“- Formik einrichten: Sie haben gelernt, wie Sie Formik in Ihr React-Projekt integrieren.
- Formulare erstellen: Sie haben zwei Formulare erstellt - ein einfaches Login und ein komplexeres Registrierungsformular.
- Validierung mit Yup: Sie haben Validierungsregeln mit Yup definiert, um die Eingaben zu überprüfen.
- Fehlermeldungen anzeigen: Sie haben gesehen, wie Formik automatisch Fehlermeldungen an den richtigen Stellen anzeigt.
- Formulardaten verarbeiten: Sie wissen jetzt, wie Sie die Formulardaten beim Absenden verarbeiten können.
Die wichtigsten Komponenten von Formik:
Abschnitt betitelt „Die wichtigsten Komponenten von Formik:“<Formik>: Das Hauptelement, das das Formular verwaltet<Form>: Ersetzt das normale HTML-Formular<Field>: Ersetzt Eingabefelder wie<input>,<textarea>und<select><ErrorMessage>: Zeigt Fehlermeldungen an
Tipps für Ihre Formulare:
Abschnitt betitelt „Tipps für Ihre Formulare:“- Organisieren Sie Ihren Code: Halten Sie Formulare übersichtlich, indem Sie sie in eigene Komponenten auslagern.
- Validieren Sie früh: Validieren Sie Ihre Eingaben, bevor Sie sie an den Server senden, um unnötige Anfragen zu vermeiden.
- Benutzerfreundlich gestalten: Zeigen Sie klare Fehlermeldungen und deaktivieren Sie den Submit-Button während der Verarbeitung.
- Testen Sie Ihre Formulare: Stellen Sie sicher, dass Ihre Formulare auch mit falschen Eingaben richtig funktionieren.
Formik nimmt Ihnen die mühsame Arbeit ab, sodass Sie sich auf die wichtigen Teile Ihrer Anwendung konzentrieren können. Viel Erfolg bei Ihren React-Projekten!