React ohne ES6
Normalerweise definiert man eine React-Komponente als eine einfache JavaScript-Klasse:
class Greeting extends React.Component {
render() {
return <h1>Hallo, {this.props.name}</h1>;
}
}
Wenn du ES6 noch nicht verwendest, kannst du stattdessen das create-react-class
Modul verwenden:
var createReactClass = require('create-react-class');
var Greeting = createReactClass({
render: function() {
return <h1>Hallo, {this.props.name}</h1>;
}
});
Die API von ES6-Klassen ähnelt sich, mit wenigen Ausnahmen, der von createReactClass()
.
Deklarieren von Default-Props
Mit Funktionen und ES6-Klassen wird defaultProps
als Eigenschaft für die Komponente selbst definiert:
class Greeting extends React.Component {
// ...
}
Greeting.defaultProps = {
name: 'Maria'
};
Mit createReactClass()
musst du getDefaultProps()
als Funktion für das übergebene Objekt definieren:
var Greeting = createReactClass({
getDefaultProps: function() {
return {
name: 'Maria'
};
},
// ...
});
Setzen des initialen States
In ES6-Klassen kannst du den initialen State definieren, indem du im Konstruktor this.state
zuweist:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {count: props.initialCount};
}
// ...
}
Mit createReactClass()
musst du eine separate getInitialState
-Methode bereitstellen, die den initialen State zurückgibt:
var Counter = createReactClass({
getInitialState: function() {
return {count: this.props.initialCount};
},
// ...
});
Autobinding
In React-Komponenten, die als ES6-Klassen deklariert wurden, folgen Methoden der gleichen Semantik wie reguläre ES6-Klassen. Dies bedeutet, dass this
sich nicht automatisch an die Instanz bindet. Du musst im constructor explizit .bind(this)
verwenden:
class SayHello extends React.Component {
constructor(props) {
super(props);
this.state = {message: 'Hallo!'};
// Diese Zeile ist wichtig!
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
alert(this.state.message);
}
render() {
// Da `this.handleClick` gebunden ist, können wir es als Event-Handler verwenden.
return (
<button onClick={this.handleClick}>
Sag Hallo
</button>
);
}
}
Mit createReactClass()
ist dies nicht notwendig, da es alle Methoden bindet:
var SayHello = createReactClass({
getInitialState: function() {
return {message: 'Hallo!'};
},
handleClick: function() {
alert(this.state.nachricht);
},
render: function() {
return (
<button onClick={this.handleClick}>
Sag Hallo
</button>
);
}
});
Das bedeutet, dass ES6-Klassen mit etwas mehr Code für Event-Handler geliefert werden, aber die Leistung bei großen Anwendungen etwas besser ist.
Wenn der Boilerplate-Code für dich zu unattraktiv ist, kannst du die ES2022 Class Properties Syntax benutzen:
class SayHello extends React.Component {
constructor(props) {
super(props);
this.state = {message: 'Hallo!'};
}
// Die Verwendung eines Pfeils bindet hier die Methode:
handleClick = () => {
alert(this.state.message);
};
render() {
return (
<button onClick={this.handleClick}>
Sag Hallo
</button>
);
}
}
Du hast auch einige andere Möglichkeiten:
- Binde Methoden im Konstruktor.
- Verwende Pfeilfunktionen, z.B.
onClick={(e) => this.handleClick(e)}
. - Verwende weiterhin
createReactClass
.
Mixins
Hinweis:
ES6 hat keine Unterstützung für Mixins, daher sind Mixins nicht unterstützt wenn du React zusammen mit ES6-Klassen benutzt.
Wir haben auch zahlreiche Probleme in Projekten festgestellt, die Mixins verwenden, und empfehlen, diese nicht in neuem Code zu verwenden.
Dieser Abschnitt dient nur als Referenz.
Manchmal haben sehr unterschiedliche Komponenten gemeinsame Funktionen. Diese werden manchmal als Querschnittsthemen bezeichnet. Mit createReactClass
kannst du dafür ein altes mixins
-System verwenden.
var SetIntervalMixin = {
componentWillMount: function() {
this.intervals = [];
},
setInterval: function() {
this.intervals.push(setInterval.apply(null, arguments));
},
componentWillUnmount: function() {
this.intervals.forEach(clearInterval);
}
};
var createReactClass = require('create-react-class');
var TickTock = createReactClass({
mixins: [SetIntervalMixin], // Verwende das Mixin
getInitialState: function() {
return {seconds: 0};
},
componentDidMount: function() {
this.setInterval(this.tick, 1000); // Rufe eine Methode für das Mixin auf
},
tick: function() {
this.setState({seconds: this.state.seconds + 1});
},
render: function() {
return (
<p>
React wurde {this.state.seconds} Sekunden lang ausgeführt.
</p>
);
}
});
const root = ReactDOM.createRoot(document.getElementById('example'));
root.render(<TickTock />);
Wenn eine Komponente mehrere Mixins verwendet und mehrere Mixins definieren dieselbe Lifecycle-Methode (d.h. mehrere Mixins möchten eine Bereinigung durchführen, wenn die Komponente zerstört wird), werden alle Lifecycle-Methoden aufgerufen. Methoden, die für Mixins definiert wurden, werden in der Reihenfolge ausgeführt in der die Mixins aufgelistet wurden, gefolgt von einem Methodenaufruf für die Komponente.