Eine Klassenkomponente ist eine JavaScript-Klasse, die React.Component erweitert und aus einer Methode render() JSX zurückgibt. Sie liest Props aus this.props, hält State in this.state und aktualisiert ihn mit this.setState(). Funktionskomponenten mit Hooks haben sie für neuen Code ersetzt, aber Klassen werden weiterhin voll unterstützt, tauchen in vielen älteren Codebasen auf und sind der einzige Weg, eine Error Boundary zu schreiben.
Jeder Zähler behält seinen eigenen State. Füge einen dritten <Counter label="Plums" /> hinzu, und auch er beginnt bei 0.
Der Aufbau einer Klassenkomponente
import { Component } from 'react';
class Welcome extends Component {
static defaultProps = { name: 'stranger' };
constructor(props) {
super(props); // required before using this
this.state = { visits: 1 };
}
render() {
return <h1>Hello, {this.props.name}. Visit #{this.state.visits}</h1>;
}
}
- Die Klasse erweitert
Component(oderReact.Componentmitimport React from 'react'). render()ist Pflicht. Die Methode muss pur sein, wie der Körper einer Funktionskomponente:this.propsundthis.statelesen, JSX zurückgeben.this.propsenthält die Props. Sie sind schreibgeschützt.- State kann in einem
constructorgesetzt werden (zuerstsuper(props)aufrufen) oder, heute üblicher, als Klassenfeld:state = { visits: 1 };. static defaultPropsfunktioniert in React 19 für Klassen weiterhin (entfernt wurde es nur für Funktionskomponenten).
this.setState führt zusammen und kann einen Updater annehmen
setState macht zwei Dinge anders als der Setter von useState. Es führt das übergebene Objekt mit dem aktuellen State zusammen, also aktualisierst du nur die Schlüssel, die du nennst. Und wie jedes State-Update in React wird es nicht sofort angewendet, also nutze die Updater-Form, wenn der nächste Wert vom vorherigen abhängt.
„+3 with objects“ addiert eins, weil alle drei Aufrufe dasselbe this.state.likes lesen. „+3 with updaters“ addiert drei. „Move to Paris“ behält name und likes (das Zusammenführen), verliert aber zip, weil das Zusammenführen nur eine Ebene tief geht. Schreib address: { ...this.state.address, city: 'Paris' }, um es zu behalten. Das optionale zweite Argument von setState läuft nach dem Update, und die Konsole zeigt dort die neue Adresse.
Event-Handler binden
Eine Methode, die als onClick={this.handleClick} übergeben wird, wird später als einfache Funktion aufgerufen, ohne ihr Objekt, also ist this darin undefined.
Der erste Button loggt einen TypeError beim Lesen von setState auf undefined. Der zweite funktioniert, weil eine Arrow Function in einem Klassenfeld this beim Erzeugen der Instanz festhält. Die ältere Lösung, in Legacy-Code noch verbreitet, bindet im Konstruktor:
constructor(props) {
super(props);
this.state = { on: false };
this.handleClick = this.handleClick.bind(this);
}
Eine Inline-Arrow-Function, onClick={() => this.handleClick()}, funktioniert ebenfalls.
Lifecycle-Methoden
Klassen reagieren über Methoden mit festen Namen auf Mounten, Aktualisieren und Unmounten. Die, die du am häufigsten siehst:
componentDidMount(): nachdem der erste Render im DOM ist. Starte Timer, Abonnements, Anfragen.componentDidUpdate(prevProps, prevState): nach jedem Update. Vergleiche mit den vorherigen Werten, bevor du arbeitest, sonst entsteht eine Schleife.componentWillUnmount(): vor dem Entfernen. Mach rückgängig, wascomponentDidMountgestartet hat.shouldComponentUpdate(nextProps, nextState): gibfalsezurück, um einen Render zu überspringen.
Die Seite zum Lifecycle von Komponenten hat die vollständige Liste, die Reihenfolge, in der sie laufen, und eine Komponente, die jede davon loggt.
Eine Klasse in eine Funktionskomponente umwandeln
Hier ist eine Klasse, die alle drei häufigen Lifecycle-Methoden nutzt. Sie tickt jede Sekunde, loggt, wenn sich ihre Prop label ändert, und stoppt ihren Timer, wenn sie entfernt wird.
Und dieselbe Komponente als Funktion. Jede Lifecycle-Methode wird Teil eines Effekts, und zusammengehöriges Setup und Cleanup stehen nebeneinander statt in zwei Methoden.
Beide Timer zählen gleich und loggen bei jeder Änderung des Labels. Die Funktionsversion loggt außerdem einmal beim Mounten, weil ein Effekt auch nach dem ersten Render läuft. Die Schritte für jede Umwandlung:
this.props.xwird zu einer destrukturierten Prop,{ x }.- Jeder Schlüssel von
this.statewird zu einem eigenenuseState. Denk daran, dass der Setter ersetzt statt zusammenzuführen. - Methoden werden zu einfachen Funktionen in der Komponente. Kein Binden nötig.
componentDidMount,componentDidUpdateundcomponentWillUnmountwerden zuuseEffect-Aufrufen, gruppiert nach dem, was sie tun, statt danach, wann sie laufen.createRefwird zuuseRef, undstatic contextTypemitthis.contextwird zuuseContextoderuse.
Lass Error Boundaries als Klassen; für sie gibt es kein Gegenstück als Funktion.
PureComponent
Eine normale Klassenkomponente rendert jedes Mal, wenn ihr Elternteil rendert. PureComponent vergleicht zuerst die neuen Props und den neuen State mit den vorherigen, eine Ebene tief, und überspringt den Render, wenn sich nichts geändert hat. Sie ist das Gegenstück von React.memo für Klassen.
Klicke auf den Button: Nur PlainLabel rendered wird geloggt, weil PureLabel dasselbe text sieht. Übergib beiden text={'hello ' + clicks}, und beide rendern bei jedem Klick.
Der Vergleich ist flach, also hebelt ihn eine Prop aus, die bei jedem Render des Elternteils ein neues Objekt oder eine neue Funktion ist (style={{ color: 'red' }}, onClick={() => ...}). Das ist dieselbe Falle wie bei React.memo.
Was React 19 aus Klassen entfernt hat
Wenn du alten Klassencode pflegst, funktionieren einige Muster in React 19 nicht mehr:
- String-Refs (
ref="input"mitthis.refs.input). NutzecreateRef()oder einen Ref-Callback. - Legacy Context (
contextTypes,childContextTypes,getChildContext). NutzecreateContextmitstatic contextType. propTypeswerden ignoriert. Nutze TypeScript oder eigene Prüfungen.findDOMNodeist weg. Setze stattdessen eine Ref auf das DOM-Element.
Die alten Methoden componentWillMount, componentWillReceiveProps und componentWillUpdate sind ebenfalls Legacy. Sie laufen noch, sowohl unter den alten Namen als auch unter den Namen mit UNSAFE_ (UNSAFE_componentWillMount und so weiter), sind aber veraltet, und StrictMode warnt vor ihnen; verschiebe ihren Code nach componentDidMount, componentDidUpdate oder getDerivedStateFromProps.
Häufig gestellte Fragen
Sind Klassenkomponenten in React veraltet?
Nein. Sie werden in React 19 weiterhin unterstützt und funktionieren weiter, aber die React-Dokumentation empfiehlt für neuen Code Funktionskomponenten mit Hooks. Für Error Boundaries brauchst du weiterhin eine Klasse.
Was ist der Unterschied zwischen Klassen- und Funktionskomponenten?
Eine Klassenkomponente hält State in this.state, aktualisiert ihn mit this.setState und reagiert über benannte Methoden auf den Lifecycle. Eine Funktionskomponente nutzt Hooks (useState, useEffect) für dieselben Aufgaben, braucht kein this und ist kürzer.
Aktualisiert setState den State sofort?
Nein. this.setState plant ein Update ein, und React rendert später, also hat this.state direkt nach dem Aufruf noch den alten Wert. Übergib eine Funktion, this.setState((state) => ...), wenn der neue Wert vom alten abhängt, oder lies das Ergebnis im Callback des zweiten Arguments oder in componentDidUpdate.
Warum ist this in meinem Event-Handler undefined?
Eine Klassenmethode, die als onClick={this.handleClick} übergeben wird, wird ohne ihr Objekt aufgerufen, also ist this gleich undefined. Definiere den Handler als Arrow Function in einem Klassenfeld (handleClick = () => { ... }) oder binde ihn im Konstruktor.
Was ist PureComponent?
Eine Component, die das Rendern überspringt, wenn ihre Props und ihr State flach gleich den vorherigen sind. Sie ist die Klassenversion von React.memo.