navigation Navigation


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

UncontrolledExample.jsx
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.

React - Unkontrollierte Components - Beispiel

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 (oder checked 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

ControlledExample.jsx
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.

React - Kontrollierte Components - Beispiel