State und Event Handling in React
State und Event Handling
~10 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Bisher war unsere App statisch – sie zeigt immer dieselben Werte an. Echte Apps müssen sich merken und darauf reagieren, wenn sich etwas ändert: ein Warenkorb-Zähler, ein Favoriten-Herz, ein ausgeklapptes Menü. Dafür gibt es useState.
Event Handling: von onclick zu onClick
In HTML/Vanilla-JS reagieren Sie auf Klicks mit onclick="..." (als String) oder element.addEventListener('click', ...). In React verwenden Sie stattdessen camelCase-Props wie onClick, denen Sie eine echte JavaScript-Funktion übergeben:
| Vanilla JS/HTML | React |
|---|---|
<button onclick="knopfGedrueckt()"> | <button onClick={{knopfGedrueckt}}> |
element.addEventListener('click', fn) | onClick={{fn}} direkt als Prop |
| Event-Objekt heißt browserabhängig unterschiedlich | Event-Objekt ist vereinheitlicht ("SyntheticEvent"), funktioniert überall gleich |
function KlickZaehler() {
function handleClick() {
console.log('Geklickt!');
}
return <button onClick={handleClick}>Klick mich</button>;
}Achtung: Häufiger Anfängerfehler: onClick={{handleClick()}} (mit Klammern) statt onClick={{handleClick}} (ohne Klammern). Mit Klammern wird die Funktion SOFORT beim Rendern ausgeführt, nicht erst beim Klick – Sie übergeben React nicht die Funktion selbst, sondern deren Rückgabewert.
useState() Grundlagen
React ändert niemals direkt, was angezeigt wird – Sie ändern einen Zustand (State), und React aktualisiert automatisch alles, was von diesem Zustand abhängt. Vergleichbar mit einer Excel-Zelle, die sich automatisch neu berechnet, wenn eine andere Zelle sich ändert, auf die sie verweist.
import { useState } from 'react';
function Zaehler() {
const [anzahl, setAnzahl] = useState(0);
return (
<div>
<p>Aktueller Wert: {anzahl}</p>
<button onClick={() => setAnzahl(anzahl + 1)}>+ 1</button>
</div>
);
}useState(0) erzeugt einen Zustandswert, der mit 0 startet, und gibt ein Array mit zwei Elementen zurück: den aktuellen Wert (anzahl) und eine Funktion, um ihn zu ändern (setAnzahl). Sie rufen NIE anzahl = 5 direkt auf – immer nur über die Setter-Funktion. Jeder Aufruf von setAnzahl(...) lässt React die Komponente neu zeichnen ("re-rendern") mit dem neuen Wert.
| Vanilla JS | React |
|---|---|
let anzahl = 0; + manuelles DOM-Update an jeder Stelle | const [anzahl, setAnzahl] = useState(0); – React aktualisiert automatisch |
Globaler Zustand z. B. via globaler Variable oder localStorage | State bleibt standardmäßig lokal in der Komponente, die ihn erzeugt hat |
ProductCard.jsx um Favoriten-Status erweitern
Jetzt kombinieren wir beides: einen Klick-Handler UND useState. Ersetzen Sie den Inhalt von src/components/ProductCard.jsx durch diese erweiterte Version:
import { useState } from 'react';
function ProductCard({ name, price, imageUrl, onSelect }) {
const [isFavorite, setIsFavorite] = useState(false);
function handleFavoriteClick(event) {
event.stopPropagation(); // verhindert, dass onSelect der Karte mitausgelöst wird
setIsFavorite(!isFavorite);
}
return (
<div className="product-card" onClick={onSelect}>
<img src={imageUrl} alt={name} className="product-card__image" />
<div className="product-card__info">
<h3 className="product-card__name">{name}</h3>
<p className="product-card__price">{price.toFixed(2)} €</p>
</div>
<button className="product-card__favorite" onClick={handleFavoriteClick}>
{isFavorite ? '♥' : '♡'}
</button>
</div>
);
}
export default ProductCard;event.stopPropagation() ist hier wichtig und ein Unterschied zu React Native: Im Browser "blubbern" Klick-Events standardmäßig nach oben durch verschachtelte Elemente ("Event Bubbling") – ohne diese Zeile würde ein Klick auf das Herz-Symbol AUCH den onClick der äußeren Karte auslösen. {{isFavorite ? '♥' : '♡'}} ist ein "ternärer Operator", die kompakte Kurzform für if/else in einem Ausdruck.
Achtung: Jede Komponenten-Instanz hat ihren EIGENEN, unabhängigen State. Sobald wir ab Kapitel 8 mehrere <ProductCard /> gleichzeitig anzeigen, hat jede ihren eigenen isFavorite-Zustand – das Anklicken des Herzens bei einer Karte beeinflusst die anderen nicht.