Elementen Kontrolle
React bietet zwei Ansätze zur Handhabung von Formularelementen: kontrollierte und unkontrollierte Komponenten. Diese grundlegenden Konzepte bestimmen, wie Daten zwischen der Benutzeroberfläche und der Anwendungslogik fließen. Während kontrollierte Komponenten durch React-State gesteuert werden und jede Änderung durch Handler-Funktionen verarbeiten, überlassen unkontrollierte Komponenten die Datenverwaltung dem DOM selbst. Die Wahl zwischen diesen Ansätzen beeinflusst direkt die Komplexität, Performance und Flexibilität der Anwendung.
Unkontrollierte Components
Bei unkontrollierten Components überlässt React die Verwaltung der Formulardaten dem DOM.
Wie funktioniert das?
Man rendert ein Formularelement, aber man übergibt ihm keinen value
Wert (oder checked
für Checkboxen), um seinen aktuellen Wert zu steuern. Um den Wert auszulesen, wenn man ihn benötigt (bspw. bei onSubmit
Funktion), verwendet man eine ref
. Eine ref
gibt direkten Zugriff auf das zugrundeliegende DOM-Element.
Beispiel
import { useRef } from 'react';
function UncontrolledExample() {
const refFieldName = useRef(null);
const refFieldEmail = useRef(null);
const refFieldMessage = useRef(null);
const handleSubmit = (event) => {
event.preventDefault();
// Formulardaten auslesen
const formData = {
name: refFieldName.current.value,
email: refFieldEmail.current.value,
message: refFieldMessage.current.value
};
console.log(JSON.stringify(formData));
// Formular zurücksetzen
refFieldName.current.value = '';
refFieldEmail.current.value = '';
refFieldMessage.current.value = '';
};
return (
<form>
<label>Name</label>
<input type="text" defaultValue="John Doe" ref={refFieldName} />
<hr />
<label>E-Mail</label>
<input type="email" defaultValue="example@mail.com" ref={refFieldEmail} />
<hr />
<label>Nachricht</label>
<textarea
rows="3"
defaultValue="Ihre Nachricht hier"
ref={refFieldMessage}
></textarea>
<hr />
<button type="submit" onClick={handleSubmit}>
Absenden
</button>
</form>
);
}
export default UncontrolledExample;
Was passiert hier?
Mit useRef(null)
erstellen wir ref
-Objekte. Die Werte refField{fieldname}.current
werden auf die DOM-Elemente zeigen, sobald sie gerendert werden.
In der Funktion handleSubmit
greifen wir refField{fieldname}.current
direkt auf die Werte zu, welche in Eingabefelder eingegeben werden.
Im Formular wird defaultValue
an Eingabefeldern verwendet. Damit kann man einen initialen Wert setzen. Nach der ersten Eingabe hat defaultValue
keinen Einfluss mehr.
Kontrollierte Components
Bei kontrollierten Components übernimmt React die volle Kontrolle über die Formulardaten. Der Wert des Formularfeldes wird durch den React-State bestimmt. Jede Änderung am Eingabefeld aktualisiert den React-State und dieser aktualisierte State wird dann zurück an das Eingabefeld als value
gegeben.
Wie funktioniert das?
- Man speichert den Wert des Formularfeldes in einem React-State (mit
useState
). - Man übergibt diesen State als
value
-Prop (oderchecked
usw.) an das Formular-Element. - Man stellt eine
onChange
Funktion bereit. Diese Funktion wird bei jeder Änderung im Eingabefeld aufgerufen und ist dafür zuständig, den React-State zu aktualisieren.
Beispiel
import { useState } from 'react';
function ControlledExample() {
const [fieldName, setFieldName] = useState('John Doe');
const [fieldEmail, setFieldEmail] = useState('example@mail.com');
const [fieldMessage, setFieldMessage] = useState('Deine Nachricht');
const isFormValid = fieldName.trim() && fieldEmail.trim() && fieldMessage.trim();
const handleSubmit = (event) => {
event.preventDefault();
if (isFormValid) {
const formData = { fieldName, fieldEmail, fieldMessage };
console.log(JSON.stringify(formData));
// Formular zurücksetzen
setFieldName('');
setFieldEmail('');
setFieldMessage('');
}
};
return (
<form onSubmit={handleSubmit}>
<label>Name</label>
<input type="text" value={fieldName} onChange={(e) => setFieldName(e.target.value)} />
<hr />
<label>E-Mail</label>
<input type="email" value={fieldEmail} onChange={(e) => setFieldEmail(e.target.value)} />
<hr />
<label>Nachricht</label>
<textarea
rows="3"
value={fieldMessage}
onChange={(e) => setFieldMessage(e.target.value)}
></textarea>
<hr />
<button
type="submit"
disabled={!isFormValid}
>
{isFormValid ? 'Absenden' : 'Formular unvollständig'}
</button>
</form>
);
}
export default ControlledExample;
In diesem Beispiel verwaltet React den kompletten Zustand über useState
. Jede Änderung löst ein Re-Rendering aus. Man kann sofort auf Änderungen (Live-Validierung, Formatierung, etc.) reagieren.
Statt defaultValue
wird value
Prop verwendet.
Der Handler onChange
ist zwingend erforderlich.