Menu

React-Klassenkomponenten: State, Lifecycle, Umwandlung

Eine Klassenkomponente ist eine JavaScript-Klasse, die React.Component erweitert und aus einer render-Methode JSX zurückgibt. Lerne this.props, this.state und setState, das Binden von Event-Handlern, Lifecycle-Methoden, PureComponent und wie du eine Klasse in eine Funktionskomponente umwandelst.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

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 (oder React.Component mit import React from 'react').
  • render() ist Pflicht. Die Methode muss pur sein, wie der Körper einer Funktionskomponente: this.props und this.state lesen, JSX zurückgeben.
  • this.props enthält die Props. Sie sind schreibgeschützt.
  • State kann in einem constructor gesetzt werden (zuerst super(props) aufrufen) oder, heute üblicher, als Klassenfeld: state = { visits: 1 };.
  • static defaultProps funktioniert 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, was componentDidMount gestartet hat.
  • shouldComponentUpdate(nextProps, nextState): gib false zurü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:

  1. this.props.x wird zu einer destrukturierten Prop, { x }.
  2. Jeder Schlüssel von this.state wird zu einem eigenen useState. Denk daran, dass der Setter ersetzt statt zusammenzuführen.
  3. Methoden werden zu einfachen Funktionen in der Komponente. Kein Binden nötig.
  4. componentDidMount, componentDidUpdate und componentWillUnmount werden zu useEffect-Aufrufen, gruppiert nach dem, was sie tun, statt danach, wann sie laufen.
  5. createRef wird zu useRef, und static contextType mit this.context wird zu useContext oder use.

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" mit this.refs.input). Nutze createRef() oder einen Ref-Callback.
  • Legacy Context (contextTypes, childContextTypes, getChildContext). Nutze createContext mit static contextType.
  • propTypes werden ignoriert. Nutze TypeScript oder eigene Prüfungen.
  • findDOMNode ist 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.

Illustration der Programmiersprachen bei Coddy

Lerne mit Coddy zu programmieren

LOS GEHT'S