Conversione di React.createClass in React.Component
Nel mio ultimo articolo ho parlato dell’applicazione di patch alle versioni precedenti di React per funzionare in un ambiente moderno. In questo articolo vado oltre e fornisco una guida passo passo per aggiornare un componente React classico a uno moderno, cambiando il React.createClass
modo di fare le cose al metodo moderno e preferito React.Component
.
I file di cui abbiamo bisogno saranno nelle cartelle "Originale" e "Finale" della directory dei componenti nella soluzione GitHub di accompagnamento.
Ottieni file tutorial da GitHub
Sempre funzionante con il componente [react-checkbox-list](https://github.com/sonyan/react-checkbox-list)
Sony An (disponibile come react-checkbox-list
su npm ). Questa guida ti mostra passo dopo passo come sostituire la struttura ei metodi di un React.createClass
componente classico con uno moderno React.Component
.
A partire dal .jsx
file nella react-checkbox-list
soluzione, elimineremo prima il .js
file e lo rinomineremo in .js
quanto .jsx
non è più necessario nominare i file in modo diverso.
Questo ci dà il seguente codice di partenza:
Conversione del componente
Quando proviamo a caricare questo codice, il primo errore che otteniamo èUncaught Error: Module build failed: SyntaxError: The @jsx React.DOM pragma has been deprecated as of React 0.12
Errore non rilevato: build del modulo non riuscita: SyntaxError: il pragma @jsx React.DOM è stato deprecato a partire da React 0.12
È abbastanza semplice correggere questo. Basta rimuovere la linea /** @jsx React.DOM */
dalla parte superiore del documento.
Ora otteniamo l’errore Uncaught TypeError: Cannot read property 'array' of undefined
come nel tutorial sull’applicazione delle patch. Questo perché React.propTypes è stato deprecato in React versione 15.50, quindi come da quel tutorial, vai avanti e installa il pacchetto PropTypes con il comando tramite npm. Lo importeremo nel nostro pacchetto in seguito.[React.createClass](https://wholesomecode.ltd/blog/broken-react-createclass-component-lets-fix-it/)
npm install --save prop-types
Quello che segue ora è una revisione completa della base di codice, quindi non possiamo aggiornare e correggere un errore come avremmo potuto fare in precedenza, quindi non sapremo se ha funzionato fino alla fine. Allaccia le cinture!
Iniziamo sostituendo la React.createClass
funzione dichiarando un nuovo React.Component
. Modifica il nostro codice in modo che appaia come segue:
'use strict';
import React from 'react';
class CheckBoxList extends React.Component {
...
}
Nota che abbiamo fatto alcune cose qui:
- Rimosso il commento JSX di apertura
- Modificato il tipo di dichiarazione da
var React =...
aimport React from 'react';
questo è il modo moderno di fare dichiarazioni in React. - Ora dichiariamo una nuova classe di
CheckBoxList
, invece di esportare una funzione. - A causa della sintassi dell’oggetto ora racchiusa tra parentesi
{...}
, è necessario eliminare la chiusura);
Tuttavia, a questa nuova classe manca ora un modo per essere esportata in modo che altri componenti possano utilizzarla, quindi aggiungiamo una dichiarazione di esportazione in fondo a quel codice.
'use strict';
import React from 'react';
class CheckBoxList extends React.Component {
...
}
export default CheckBoxList;
Nel nostro codice originale, la prima riga di codice nella funzione era displayName: 'CheckBoxList',
la nostra esportazione ora gestisce questo, quindi possiamo rimuovere completamente quel codice.
La riga successiva dichiara che i nostri propTypes
questi ora si trovano al di fuori della classe e hanno bisogno della PropTypes
dipendenza che abbiamo aggiunto tramite npm. Aggiungiamolo alle nostre importazioni e scriviamo i PropType in questo modo:
'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;
Successivamente lo stato viene dichiarato tramite il metodo getInitialState
con React.Component
impostiamo il nostro stato iniziale con un costruttore. Aggiungi il seguente codice nella nostra build:
...
class CheckBoxList extends React.Component {
constructor( props) {
super( props );
this.state = {
data: [],
}
}
...
}
...
Ecco, questo imposta lo stato del componente, ma aspetta, non gli abbiamo effettivamente detto da dove ottenere il suo stato. Ecco dove componentWillMount
torna utile.
...
class CheckBoxList extends React.Component {
constructor( props) {
super( props );
this.state = {
data: [],
}
}
componentWillMount() {
this.setState({
data: this.props.defaultData,
});
}
...
}
...
Una cosa fondamentale da notare è che i metodi interni di React.Component
non terminano con virgole (,
), quindi assicurati che tutti i metodi che aggiungi al componente non terminino con una virgola!
Successivamente, aggiungiamo nuovamente la funzione di rendering. Questa è probabilmente la parte più semplice, è quasi la stessa, con la differenza fondamentale che cambiamo render: function() {
in solo render() {
.
Ai fini di mantenere questo tutorial al punto, non convertirò i due metodi reset
e checkAll
tuttavia i concetti utilizzati per il port del metodo handleItemChange
apple in entrambi, quindi sentiti libero di provarli tu stesso.
Per migrare il handleItemChange
metodo, dobbiamo prima rimuovere la virgola di chiusura (,
) e modificare il tipo di dichiarazione della funzione handleItemChange: function(e) {
per handleItemChange( e) {
assicurarci di passare ancora e
come parametro dell’evento.
Aggiungiamolo sopra il nostro metodo di rendering.
...
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);
}
}
...
}
...
Il nostro componente verrà ora renderizzato, tuttavia non sarà funzionale. Quando si tenta di fare clic su una casella di controllo verrà visualizzato l’errore Uncaught TypeError: Cannot read property 'state' of undefined
.
TypeError non rilevato: impossibile leggere la proprietà ‘state’ di undefined
Questo perché nel nostro handleItemChange
metodo, dove proviamo ad accedere allo stato, this
è indefinito. Per risolvere questo problema, dobbiamo associare la nostra funzione this
aggiungendo la seguente riga nel nostro costruttore: this.handleItemChange = this.handleItemChange.bind( this );
.
...
class CheckBoxList extends React.Component {
constructor( props) {
super( props );
this.state = {
data: [],
}
this.handleItemChange = this.handleItemChange.bind( this );
}
...
}
...
E il gioco è fatto, il nostro componente React appena convertito in azione.
React.createClass a React.Component
Codice sorgente dell’esercitazione
Puoi scaricare il codice sorgente per la versione originale e finale del componente su GitHub. Il plug-in contiene un blocco Gutenberg di WordPress che puoi utilizzare per giocare con il codice, con tre file che puoi eliminare a seconda dei casi:
I file del tutorial di GitHub per la conversione da React.createClass a React.Component