Events in React
Bisher waren unsere Komponenten rein darstellend — sie empfangen Props und rendern JSX. Aber eine echte Anwendung muss auf Benutzerinteraktionen reagieren: Klicks, Eingaben, Formulare. Dafür gibt es Event-Handler.
Event-Handler hinzufügen
Abschnitt betitelt „Event-Handler hinzufügen“Ein Event-Handler ist eine Funktion, die React aufruft, wenn ein bestimmtes Event eintritt. Du übergibst sie als Prop an ein JSX-Element:
function App() { function handleClick() { alert("Button wurde geklickt!"); }
return <button onClick={handleClick}>Klick mich</button>;}Drei Dinge sind hier wichtig:
- Die Funktion wird definiert —
handleClickist eine normale Funktion innerhalb der Komponente. - Die Funktion wird übergeben, nicht aufgerufen —
onClick={handleClick}ohne(). Mit()würde die Funktion sofort beim Rendern ausgeführt, nicht erst beim Klick. onClickstattonclick— React verwendet camelCase für Event-Props.
Namenskonvention
Abschnitt betitelt „Namenskonvention“In React hat sich die Konvention handle + Eventname etabliert:
function handleClick() { /* ... */ }function handleChange() { /* ... */ }function handleSubmit() { /* ... */ }function handleMouseEnter() { /* ... */ }Das ist eine Konvention, keine Pflicht. Für einfache Fälle oder Inline-Handler musst du dich nicht daran halten — niemand benennt jede anonyme Arrow-Function nach diesem Schema. Die Konvention hilft vor allem, wenn eine Komponente mehrere Handler hat und du auf einen Blick sehen willst, was wozu gehört.
Inline-Varianten
Abschnitt betitelt „Inline-Varianten“Für kurze Handler kannst du die Funktion direkt inline schreiben:
// Arrow Function<button onClick={() => alert("Klick!")}>Klick mich</button>
// Auch mehrzeilig<button onClick={() => { console.log("Klick!"); alert("Klick!");}}> Klick mich</button>Inline-Handler sind praktisch bei kurzer Logik. Bei mehr als zwei Zeilen lohnt es sich, die Funktion herauszuziehen — nicht wegen einer Regel, sondern weil es lesbarer wird.
Das Event-Objekt
Abschnitt betitelt „Das Event-Objekt“Jeder Event-Handler bekommt automatisch ein Event-Objekt als erstes Argument. Schau es dir mit console.log an:
function App() { function handleClick(event) { console.log(event); }
return <button onClick={handleClick}>Klick mich</button>;}In der Konsole siehst du ein SyntheticBaseEvent — nicht das native Browser-Event. React wickelt alle Events in eigene Objekte ein, die über alle Browser hinweg identisch funktionieren. Du kannst sie aber genauso verwenden wie native Events:
function handleClick(event) { console.log(event.target); // das geklickte DOM-Element console.log(event.clientX); // X-Position des Klicks console.log(event.nativeEvent); // das originale Browser-Event}Das SyntheticBaseEvent hat die gleichen Properties und Methoden wie das native Event (target, preventDefault(), stopPropagation(), …) — mit dem Unterschied, dass es in jedem Browser gleich aussieht.
Event-Typ mit JSDoc
Abschnitt betitelt „Event-Typ mit JSDoc“Wenn du in reinem JavaScript (ohne TypeScript) arbeitest, kannst du den Event-Typ mit JSDoc dokumentieren:
/** * @param {React.MouseEvent<HTMLButtonElement>} event */function handleClick(event) { console.log(event.clientX);}Dein Editor (z.B. VS Code) bietet dir dann Autocomplete und Typprüfung für alle Properties des Events. Woher kommt der Typ? React definiert eigene Event-Interfaces wie React.MouseEvent, React.ChangeEvent, React.FormEvent usw. — passend zum jeweiligen Event. Der Typ-Parameter in spitzen Klammern (z.B. <HTMLButtonElement>) gibt an, auf welchem DOM-Element das Event ausgelöst wird.
Events bei eigenen Komponenten
Abschnitt betitelt „Events bei eigenen Komponenten“HTML-Elemente wie <button> oder <input> haben eingebaute Event-Props (onClick, onChange, …). Aber was ist mit eigenen Komponenten?
Eigene Komponenten haben keine eingebauten Events. Wenn du <MeinButton onClick={...} /> schreibst, ist onClick einfach ein Prop wie jeder andere — ein Callback, den die Komponente intern an ein HTML-Element weitergibt:
function MeinButton({ onClick, children }) { return <button onClick={onClick}>{children}</button>;}
function App() { return ( <MeinButton onClick={() => alert("Klick!")}> Klick mich </MeinButton> );}MeinButton empfängt onClick als Prop und gibt es an den nativen <button> weiter. Das Event wird also nicht von MeinButton ausgelöst, sondern vom <button> darin.
Namenskonvention bei eigenen Komponenten
Abschnitt betitelt „Namenskonvention bei eigenen Komponenten“Für Event-Props eigener Komponenten gibt es eine klare Konvention:
- Props beginnen mit
on:onClick,onDelete,onSearch - Handler beginnen mit
handle:handleClick,handleDelete,handleSearch
function SucheingabeFeld({ onSearch }) { function handleChange(event) { onSearch(event.target.value); }
return <input onChange={handleChange} placeholder="Suchen..." />;}
function App() { function handleSearch(suchbegriff) { console.log("Suche nach:", suchbegriff); }
return <SucheingabeFeld onSearch={handleSearch} />;}Beachte den Unterschied: SucheingabeFeld bekommt onSearch (was passieren soll) und entscheidet intern, wann es aufgerufen wird (bei onChange des Inputs). Die Elternkomponente definiert das Verhalten, die Kindkomponente steuert den Zeitpunkt.
Propagation und Default-Verhalten
Abschnitt betitelt „Propagation und Default-Verhalten“Event-Propagation (Bubbling)
Abschnitt betitelt „Event-Propagation (Bubbling)“Events in React „blubbern” nach oben — genau wie im DOM. Wenn du auf ein Element klickst, wird das Event an alle Elternelemente weitergegeben:
function App() { return ( <div onClick={() => console.log("div geklickt")}> <button onClick={() => console.log("button geklickt")}> Klick mich </button> </div> );}Ein Klick auf den Button löst beide Handler aus:
"button geklickt"(das direkte Ziel)"div geklickt"(das Event blubbert zum<div>hoch)
Um das zu verhindern, rufst du event.stopPropagation() auf:
function App() { return ( <div onClick={() => console.log("div geklickt")}> <button onClick={(event) => { event.stopPropagation(); console.log("button geklickt"); }}> Klick mich </button> </div> );}Jetzt wird nur "button geklickt" ausgegeben — das Event erreicht den <div> nicht mehr.
Default-Verhalten verhindern
Abschnitt betitelt „Default-Verhalten verhindern“Manche HTML-Elemente haben ein eingebautes Verhalten. Zum Beispiel lädt ein <form> beim Absenden die Seite neu. Das willst du in einer React-App fast nie:
function Anmeldeformular() { function handleSubmit(event) { event.preventDefault(); console.log("Formular abgeschickt — ohne Seitenneuladen"); }
return ( <form onSubmit={handleSubmit}> <input type="text" placeholder="Benutzername" /> <button type="submit">Anmelden</button> </form> );}event.preventDefault() verhindert das Standard-Verhalten des Browsers — die Seite wird nicht neu geladen, und du kannst das Formular in JavaScript verarbeiten.
Unterschied auf einen Blick
Abschnitt betitelt „Unterschied auf einen Blick“| Methode | Was sie tut |
|---|---|
event.stopPropagation() | Verhindert, dass das Event an Elternelemente weitergegeben wird |
event.preventDefault() | Verhindert das Standard-Verhalten des Browsers (z.B. Seitenneuladen bei <form>) |
Beide Methoden sind unabhängig voneinander — du kannst sie einzeln oder zusammen verwenden.
Zusammenfassung
Abschnitt betitelt „Zusammenfassung“| Konzept | Beschreibung |
|---|---|
| Event-Handler | Funktionen, die als Props übergeben werden: onClick={handleClick} |
| Übergeben, nicht aufrufen | onClick={handleClick} — ohne () |
| Inline-Handler | onClick={() => alert("Klick!")} — für kurze Logik |
| Event-Objekt | SyntheticBaseEvent — Reacts browserübergreifender Event-Wrapper |
| Eigene Komponenten | Event-Props sind Callbacks: onSearch, onDelete |
| Propagation | Events blubbern nach oben — stopPropagation() verhindert das |
| Default-Verhalten | preventDefault() verhindert Browser-Standardaktionen |