Konvertieren von React.createClass in React.Component
In meinem letzten Artikel habe ich darüber gesprochen, ältere Versionen von React zu patchen, damit sie in einer modernen Umgebung funktionieren. In diesem Artikel gehe ich noch einen Schritt weiter und gebe eine Schritt-für-Schritt-Anleitung zum Upgrade einer klassischen React-Komponente auf eine moderne, indem ich die React.createClass
Vorgehensweise auf die moderne und bevorzugte React.Component
Methode umstelle.
Die benötigten Dateien befinden sich in den Ordnern „Original” und „Final” des Komponentenverzeichnisses in der begleitenden GitHub-Lösung.
Holen Sie sich Tutorial-Dateien von GitHub
Arbeite wieder mit der Komponente [react-checkbox-list](https://github.com/sonyan/react-checkbox-list)
von Sony An (erhältlich unter react-checkbox-list
npm ). Diese Anleitung zeigt Ihnen Schritt für Schritt, wie Sie die Struktur und Methoden einer klassischen React.createClass
Komponente durch eine moderne ersetzen React.Component
.
Beginnend mit der .jsx
Datei in der react-checkbox-list
Lösung löschen wir zunächst die .js
Datei und benennen diese um, .js
da .jsx
Dateien nicht mehr anders benannt werden müssen.
Das gibt uns den folgenden Startcode:
Konvertieren der Komponente
Beim Versuch, diesen Code zu laden, erhalten wir als ersten FehlerUncaught Error: Module build failed: SyntaxError: The @jsx React.DOM pragma has been deprecated as of React 0.12
Nicht erfasster Fehler: Modulerstellung fehlgeschlagen: SyntaxError: Das Pragma @jsx React.DOM ist seit React 0.12 veraltet
Es ist einfach genug, dies zu korrigieren. Entfernen Sie einfach die Linie /** @jsx React.DOM */
am oberen Rand des Dokuments.
Wir bekommen jetzt Uncaught TypeError: Cannot read property 'array' of undefined
den gleichen Fehler wie im Patching- [React.createClass](https://wholesomecode.ltd/blog/broken-react-createclass-component-lets-fix-it/)
Tutorial. Dies liegt daran, dass React.propTypes in React Version 15.50 veraltet war. Fahren Sie also gemäß diesem Tutorial fort und installieren Sie das PropTypes-Paket mit dem Befehl über npm. Wir werden dies später in unser Paket importieren.
npm install --save prop-types
Was jetzt folgt, ist eine vollständige Überarbeitung der Codebasis, sodass wir einen Fehler nicht aktualisieren und beheben können, wie wir es möglicherweise zuvor getan haben, sodass wir bis zum Ende nicht wissen, ob es funktioniert hat. Anschnallen!
Beginnen wir damit, die React.createClass
Funktion zu ersetzen, indem wir eine neue deklarieren React.Component
. Ändern Sie unseren Code so, dass er wie folgt aussieht:
'use strict';
import React from 'react';
class CheckBoxList extends React.Component {
...
}
Beachten Sie, dass wir hier einige Dinge getan haben:
- Der öffnende JSX-Kommentar wurde entfernt
var React =...
Der Deklarationstyp wurde von in geändertimport React from 'react';
. Dies ist die moderne Art, Deklarationen in React vorzunehmen.- Wir deklarieren jetzt eine neue Klasse von
CheckBoxList
, anstatt eine Funktion zu exportieren. - Aufgrund der Syntax des Objekts, das jetzt in Klammern eingeschlossen ist
{...}
, müssen wir das Schließen weglassen);
Dieser neuen Klasse fehlt jetzt jedoch eine Möglichkeit, sie zu exportieren, damit andere Komponenten sie verwenden können. Fügen wir also am Ende dieses Codes eine Exportdeklaration hinzu.
'use strict';
import React from 'react';
class CheckBoxList extends React.Component {
...
}
export default CheckBoxList;
In unserem ursprünglichen Code war die erste Codezeile in der Funktion displayName: 'CheckBoxList',
unser Export behandelt dies jetzt, sodass wir diesen Code vollständig entfernen können.
Die nächste Zeile unten erklärt, dass propTypes
diese jetzt außerhalb der Klasse sitzen und die Abhängigkeit benötigen, die PropTypes
wir über npm hinzugefügt haben. Fügen wir das unseren Importen hinzu und schreiben die PropTypes wie folgt:
'use strict';
import React from 'react';
import PropTypes from 'prop-types';
class CheckBoxList extends React.Component {
...
}
CheckBoxList.propTypes = {
defaultData: PropTypes.array,
onChange: PropTypes.func,
};
export default CheckBoxList;
Als nächstes wird der Zustand über die Methode deklariert, getInitialState
wobei React.Component
wir unseren Anfangszustand mit einem Konstruktor festlegen. Fügen Sie den folgenden Code in unseren Build ein:
...
class CheckBoxList extends React.Component {
constructor( props) {
super( props );
this.state = {
data: [],
}
}
...
}
...
Los geht’s, das legt den Zustand der Komponente fest, aber Moment mal, wir haben ihr nicht wirklich gesagt, woher sie ihren Zustand bekommen soll. Das ist, wo componentWillMount
kommt in handliches.
...
class CheckBoxList extends React.Component {
constructor( props) {
super( props );
this.state = {
data: [],
}
}
componentWillMount() {
this.setState({
data: this.props.defaultData,
});
}
...
}
...
Beachten Sie unbedingt, dass die inneren Methoden von React.Component
nicht mit Kommas (,
) enden. Stellen Sie also sicher, dass alle Methoden, die Sie der Komponente hinzufügen, nicht mit Kommas enden!
Als nächstes fügen wir die Render-Funktion wieder hinzu. Dies ist wahrscheinlich der einfachste Teil, es ist fast derselbe, mit dem Hauptunterschied, dass wir render: function() {
nur zu render() {
.
Um dieses Tutorial auf den Punkt zu bringen, werde ich die beiden Methoden reset
und checkAll
die Konzepte, die für die Portierung der Methode handleItemChange
apple verwendet werden, nicht auf beide umwandeln, also probieren Sie es ruhig selbst aus.
Um die Methode zu migrieren handleItemChange
, müssen wir zunächst das schließende Komma () entfernen und den Deklarationstyp der Funktion von in ,
ändern, um sicherzustellen, dass wir immer noch als Ereignisparameter übergeben.handleItemChange: function(e) {``handleItemChange( e) {``e
Lassen Sie uns das über unserer Rendermethode hinzufügen.
...
class CheckBoxList extends React.Component {
...
handleItemChange( e) {
var selectedValues = [],
newData = [];
this.state.data.forEach(function(item) {
if(item.value == e.target.value) {
item.checked = e.target.checked;
}
if(item.checked) {
selectedValues.push(item.value);
}
newData.push(item);
});
this.setState( {data: newData} );
if(this.props.onChange) {
this.props.onChange(selectedValues);
}
}
...
}
...
Unsere Komponente wird jetzt gerendert, ist jedoch nicht funktionsfähig. Wenn Sie versuchen, auf ein Kontrollkästchen zu klicken, erhalten Sie den Fehler Uncaught TypeError: Cannot read property 'state' of undefined
.
Uncaught TypeError: Eigenschaft ‘state’ von undefined kann nicht gelesen werden
Dies liegt daran, dass unsere handleItemChange
Methode, mit der wir versuchen, auf den Zustand zuzugreifen, this
undefiniert ist. Um dies zu beheben, müssen wir unsere Funktion an binden, this
indem wir die folgende Zeile in unseren Konstruktor einfügen: this.handleItemChange = this.handleItemChange.bind( this );
.
...
class CheckBoxList extends React.Component {
constructor( props) {
super( props );
this.state = {
data: [],
}
this.handleItemChange = this.handleItemChange.bind( this );
}
...
}
...
Und da haben wir sie, unsere neu konvertierte React-Komponente in Aktion.
React.createClass zu React.Component
Tutorial-Quellcode
Sie können den Quellcode für die ursprüngliche und endgültige Version der Komponente auf GitHub herunterladen. Das Plugin enthält einen WordPress-Gutenberg-Block, mit dem Sie mit dem Code herumspielen können, mit drei Dateien, die Sie gegebenenfalls löschen können:
Die GitHub-Tutorial-Dateien für die Umwandlung von React.createClass in React.Component