Klassenkomponenten waren vor der Einführung von Hooks (mit React 16.8, Februar 2019) weit verbreitet
Heute verlagert sich der Fokus hin zu Hooks
Gründe für die Verwendung von Hooks:
this
Gründe für die Verwendung von Klassenkomponenten:
import { Component } from 'react';
class App extends Component {
constructor(props) {
// ...
this.state = { name: 'World' };
}
render() {
return <div>Hello, {this.state.name}!</div>;
}
}
export default App;
Props können via this.props
ausgelesen werden:
type TodoItemProps = {
todo: Todo;
onDelete: (id: number) => void;
};
class TodoItem extends Component<TodoItemProps> {
render() {
return (
<li>
{this.props.todo.completed ? 'DONE: ' : 'TODO: '}
{this.props.todo.title}
</li>
);
}
}
In Klassenkomponenten repräsentiert this.state
den aktuellen state
this.state
ist immer ein JavaScript-Objekt mit verschiedenen Einträgen (Properties)
Zustandsänderungen erfolgen über this.setState()
this.state ist ein JavaScript-Objekt:
{
"todos": [],
"loadingStatus": "idle"
}
type TodoAppProps = {};
type TodoAppState = {
todo: Array<Todo>;
loadingStatus: string;
};
class TodoApp extends Component<
TodoAppProps,
TodoAppState
> {
// ...
}
Der State muss im Konstruktor initialisiert werden
Der Konstruktor erhält auch die Props der Komponente als Argument
constructor(props: TodoAppProps) {
super(props);
this.state = {
todos: [],
loadingStatus: "idle",
}
}
In JavaScript muss der Konstruktor der Elternklasse (Component
) im Konstruktor aufgerufen werden (geschieht via super()
)
this.setState({ loadingStatus: 'loading' });
setState überschreibt alle angegebenen Einträge im state-Objekt und lässt den Rest unverändert
in Klassenkomponenten - insbesondere in Eventhandlern - kann this
manchmals falsch gesetzt sein
allgemeines Problem: Methodenaufrufe ohne Methodensyntax:
class Foo {
constructor() {
this.message = 'hello';
}
greet() {
console.log(this.message);
}
}
const foo = new Foo();
foo.greet(); // ok
const greet = foo.greet;
greet(); // not ok ("this" is undefined)
Problem in einem React-Rendering:
class Foo extends Component {
// ...
greet() {
console.log(this.message);
}
render() {
return <button onClick={this.greet}>hello</button>;
}
}
Lösung A: Pfeil-Methoden:
class Foo extends Component {
// ...
greet = () => {
console.log(this.message);
};
// ...
}
Lösung B: binden der Methode im Constructor:
constructor() {
// ...
this.greet = this.greet.bind(this);
}
Konvertiere bestehende Komponenten (z.B. AddTodo
) von Funktionskomponenten zu Klassenkomponenten