{"id":228877,"date":"2022-10-12T18:54:00","date_gmt":"2022-10-12T15:54:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=228877"},"modified":"2022-11-09T04:38:08","modified_gmt":"2022-11-09T01:38:08","slug":"conversione-di-react-createclass-in-react-component","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/it\/conversione-di-react-createclass-in-react-component\/","title":{"rendered":"Conversione di React.createClass in React.Component"},"content":{"rendered":"\n<p>Nel mio <a href=\"https:\/\/wholesomecode.ltd\/blog\/broken-react-createclass-component-lets-fix-it\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ultimo articolo ho parlato dell&#8217;applicazione di patch alle versioni precedenti di React per funzionare in un ambiente moderno<\/a>. In questo articolo vado oltre e fornisco una guida passo passo per aggiornare un componente React classico a uno moderno, cambiando il <code>React.createClass<\/code>modo di fare le cose al metodo moderno e preferito <code>React.Component<\/code>.<\/p>\n<p>I file di cui abbiamo bisogno saranno nelle cartelle &quot;Originale&quot; e &quot;Finale&quot; della directory dei componenti nella soluzione GitHub di accompagnamento.<\/p>\n<p><a href=\"https:\/\/github.com\/mattwatsoncodes\/Tutorial-Convert-React-createClass-to-React-Component\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Ottieni file tutorial da GitHub<\/a><\/p>\n<p>Sempre funzionante con il componente <code>[react-checkbox-list](https:\/\/github.com\/sonyan\/react-checkbox-list)<\/code> <a href=\"https:\/\/github.com\/sonyan\/react-checkbox-list\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Sony An<\/a> (disponibile come <a href=\"https:\/\/www.npmjs.com\/package\/react-checkbox-list\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\"><code>react-checkbox-list<\/code>su npm<\/a> ). Questa guida ti mostra passo dopo passo come sostituire la struttura ei metodi di un <code>React.createClass<\/code>componente classico con uno moderno <code>React.Component<\/code>.<\/p>\n<p>A partire dal <code>.jsx<\/code>file nella <code>react-checkbox-list<\/code>soluzione, elimineremo prima il <code>.js<\/code>file e lo rinomineremo in <code>.js<\/code>quanto <code>.jsx<\/code>non \u00e8 pi\u00f9 necessario nominare i file in modo diverso.<\/p>\n<p>Questo ci d\u00e0 il seguente codice di partenza:<\/p>\n<pre><code>\n'use strict';\nvar React = require('react');\n\nmodule.exports = React.createClass({\n    displayName: 'CheckBoxList',\n\n    propTypes: {\n        defaultData: React.PropTypes.array,\n        onChange: React.PropTypes.func\n    },\n\n    getInitialState: function() {\n        return {\n            data: this.props.defaultData || []\n        };\n    },\n\n    handleItemChange: function(e) {\n        var selectedValues = [],\n            newData = [];\n\n        this.state.data.forEach(function(item) {\n            if(item.value === e.target.value) {\n                item.checked = e.target.checked;\n            }\n            if(item.checked) {\n                selectedValues.push(item.value);\n            }\n            newData.push(item);\n        });\n\n        this.setState({data: newData});\n\n        if(this.props.onChange) {\n            this.props.onChange(selectedValues);\n        }\n    },\n\n    reset: function() {\n        var newData = [];\n        this.state.data.forEach(function(item) {\n            item.checked = false;\n            newData.push(item);\n        });\n\n        this.setState({data: newData});\n    },\n\n    checkAll: function() {\n        var newData = [];\n        this.state.data.forEach(function(item) {\n            item.checked = true;\n            newData.push(item);\n        });\n\n        this.setState({data: newData});\n    },\n\n    render: function() {\n        var options;\n\n        options = this.state.data.map(function(item, index) {\n            return (&lt;div key={'chk-' + index} className=\"checkbox\"&gt;\n                    &lt;label&gt;\n                        &lt;input\n                            type=\"checkbox\"\n                            value={item.value}\n                            onChange={this.handleItemChange}\n                            checked={item.checked? true: false} \/&gt; {item.label}\n                    &lt;\/label&gt;\n                &lt;\/div&gt;\n            );\n        }.bind(this));\n\n        return (&lt;div&gt;\n                {options}\n            &lt;\/div&gt;\n        );\n    }\n});\n<\/code><\/pre>\n<h2>Conversione del componente<\/h2>\n<p>Quando proviamo a caricare questo codice, il primo errore che otteniamo \u00e8<code>Uncaught Error: Module build failed: SyntaxError: The @jsx React.DOM pragma has been deprecated as of React 0.12<\/code><\/p>\n<p>Errore non rilevato: build del modulo non riuscita: SyntaxError: il pragma <a href=\"https:\/\/hashnode.com\/@jsx\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@jsx<\/a> React.DOM \u00e8 stato deprecato a partire da React 0.12<\/p>\n<p>\u00c8 abbastanza semplice correggere questo. Basta rimuovere la linea <code>\/** @jsx React.DOM *\/<\/code>dalla parte superiore del documento.<\/p>\n<p>Ora otteniamo l&#8217;errore <code>Uncaught TypeError: Cannot read property 'array' of undefined<\/code>come nel <a href=\"https:\/\/wholesomecode.ltd\/blog\/broken-react-createclass-component-lets-fix-it\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tutorial sull&#8217;applicazione delle<\/a> <a href=\"https:\/\/wholesomecode.ltd\/blog\/broken-react-createclass-component-lets-fix-it\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">patch<\/a>. Questo perch\u00e9 React.propTypes \u00e8 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.<code>[React.createClass](https:\/\/wholesomecode.ltd\/blog\/broken-react-createclass-component-lets-fix-it\/)<\/code><a href=\"https:\/\/wholesomecode.ltd\/blog\/broken-react-createclass-component-lets-fix-it\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external\"><\/a><\/p>\n<pre><code>npm install --save prop-types\n<\/code><\/pre>\n<p>Quello che segue ora \u00e8 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!<\/p>\n<p>Iniziamo sostituendo la <code>React.createClass<\/code>funzione dichiarando un nuovo <code>React.Component<\/code>. Modifica il nostro codice in modo che appaia come segue:<\/p>\n<pre><code>'use strict';\nimport React from 'react';\n\nclass CheckBoxList extends React.Component {\n...\n}\n<\/code><\/pre>\n<p>Nota che abbiamo fatto alcune cose qui:<\/p>\n<ul>\n<li>Rimosso il commento JSX di apertura<\/li>\n<li>Modificato il tipo di dichiarazione da <code>var React =...<\/code>a <code>import React from 'react';<\/code>questo \u00e8 il modo moderno di fare dichiarazioni in React.<\/li>\n<li>Ora dichiariamo una nuova classe di <code>CheckBoxList<\/code>, invece di esportare una funzione.<\/li>\n<li>A causa della sintassi dell&#8217;oggetto ora racchiusa tra parentesi <code>{...}<\/code>, \u00e8 necessario eliminare la chiusura<code>);<\/code><\/li>\n<\/ul>\n<p>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.<\/p>\n<pre><code>'use strict';\nimport React from 'react';\n\nclass CheckBoxList extends React.Component {\n...\n}\n\nexport default CheckBoxList;\n<\/code><\/pre>\n<p>Nel nostro codice originale, la prima riga di codice nella funzione era <code>displayName: 'CheckBoxList',<\/code>la nostra esportazione ora gestisce questo, quindi possiamo rimuovere completamente quel codice.<\/p>\n<p>La riga successiva dichiara che i nostri <code>propTypes<\/code>questi ora si trovano al di fuori della classe e hanno bisogno della <code>PropTypes<\/code>dipendenza che abbiamo aggiunto tramite npm. Aggiungiamolo alle nostre importazioni e scriviamo i PropType in questo modo:<\/p>\n<pre><code>'use strict';\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nclass CheckBoxList extends React.Component {\n...\n}\n\nCheckBoxList.propTypes = {\n    defaultData: PropTypes.array,\n    onChange: PropTypes.func,\n};\n\nexport default CheckBoxList;\n<\/code><\/pre>\n<p>Successivamente lo stato viene dichiarato tramite il metodo <code>getInitialState<\/code>con <code>React.Component<\/code>impostiamo il nostro stato iniziale con un costruttore. Aggiungi il seguente codice nella nostra build:<\/p>\n<pre><code>...\nclass CheckBoxList extends React.Component {\n    constructor( props) {\n        super( props );\n        this.state = {\n            data: [],\n        }\n    }\n...\n}\n...\n<\/code><\/pre>\n<p>Ecco, questo imposta lo stato del componente, ma aspetta, non gli abbiamo effettivamente detto da dove ottenere il suo stato. Ecco dove <code>componentWillMount<\/code>torna utile.<\/p>\n<pre><code>...\nclass CheckBoxList extends React.Component {\n    constructor( props) {\n        super( props );\n        this.state = {\n            data: [],\n        }\n    }\n\n    componentWillMount() {\n        this.setState({\n            data: this.props.defaultData,\n        });\n    }\n...\n}\n...\n<\/code><\/pre>\n<p>Una cosa fondamentale da notare \u00e8 che i metodi interni di <code>React.Component<\/code>non terminano con virgole (<code>,<\/code>), quindi assicurati che tutti i metodi che aggiungi al componente non terminino con una virgola!<\/p>\n<p>Successivamente, aggiungiamo nuovamente la funzione di rendering. Questa \u00e8 probabilmente la parte pi\u00f9 semplice, \u00e8 quasi la stessa, con la differenza fondamentale che cambiamo <code>render: function() {<\/code>in solo <code>render() {<\/code>.<\/p>\n<pre><code>...\nclass CheckBoxList extends React.Component {\n...\n    render() {\n        var options;\n\n        options = this.state.data.map(function(item, index) {\n            return (&lt;div key={'chk-' + index} className=\"checkbox\"&gt;\n                    &lt;label&gt;\n                        &lt;input\n                            type=\"checkbox\"\n                            value={item.value}\n                            onChange={this.handleItemChange}\n                            checked={item.checked? true: false} \/&gt; {item.label}\n                    &lt;\/label&gt;\n                &lt;\/div&gt;\n            );\n        }.bind(this));\n\n        return (&lt;div&gt;\n                {options}\n            &lt;\/div&gt;\n        );\n    }\n...\n}\n...\n<\/code><\/pre>\n<p>Ai fini di mantenere questo tutorial al punto, non convertir\u00f2 i due metodi <code>reset<\/code>e <code>checkAll<\/code>tuttavia i concetti utilizzati per il port del metodo <code>handleItemChange<\/code>apple in entrambi, quindi sentiti libero di provarli tu stesso.<\/p>\n<p>Per migrare il <code>handleItemChange<\/code>metodo, dobbiamo prima rimuovere la virgola di chiusura (<code>,<\/code>) e modificare il tipo di dichiarazione della funzione <code>handleItemChange: function(e) {<\/code>per <code>handleItemChange( e) {<\/code>assicurarci di passare ancora <code>e<\/code>come parametro dell&#8217;evento.<\/p>\n<p>Aggiungiamolo sopra il nostro metodo di rendering.<\/p>\n<pre><code>...\nclass CheckBoxList extends React.Component {\n...\n    handleItemChange( e) {\n        var selectedValues = [],\n            newData = [];\n\n        this.state.data.forEach(function(item) {\n            if(item.value == e.target.value) {\n                item.checked = e.target.checked;\n            }\n            if(item.checked) {\n                selectedValues.push(item.value);\n            }\n            newData.push(item);\n        });\n\n        this.setState( {data: newData} );\n\n        if(this.props.onChange) {\n            this.props.onChange(selectedValues);\n        }\n    }\n...\n}\n...\n<\/code><\/pre>\n<p>Il nostro componente verr\u00e0 ora renderizzato, tuttavia non sar\u00e0 funzionale. Quando si tenta di fare clic su una casella di controllo verr\u00e0 visualizzato l&#8217;errore <code>Uncaught TypeError: Cannot read property 'state' of undefined<\/code>.<\/p>\n<p>TypeError non rilevato: impossibile leggere la propriet\u00e0 &#8216;state&#8217; di undefined<\/p>\n<p>Questo perch\u00e9 nel nostro <code>handleItemChange<\/code>metodo, dove proviamo ad accedere allo stato, <code>this<\/code>\u00e8 indefinito. Per risolvere questo problema, dobbiamo associare la nostra funzione <code>this<\/code>aggiungendo la seguente riga nel nostro costruttore: <code>this.handleItemChange = this.handleItemChange.bind( this );<\/code>.<\/p>\n<pre><code>...\nclass CheckBoxList extends React.Component {\n    constructor( props) {\n        super( props );\n        this.state = {\n            data: [],\n        }\n        this.handleItemChange = this.handleItemChange.bind( this );\n    }\n...\n}\n...\n<\/code><\/pre>\n<p>E il gioco \u00e8 fatto, il nostro componente React appena convertito in azione.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169430-61e80f22b2772.gif\" alt=\"Conversione di React.createClass in React.Component\" \/>React.createClass a React.Component<\/p>\n<h2>Codice sorgente dell&#8217;esercitazione<\/h2>\n<p>Puoi <a href=\"https:\/\/github.com\/wholesomecode\/Tutorial-Convert-React-createClass-to-React-Component\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">scaricare il codice sorgente per la versione originale e finale del componente su GitHub<\/a>. 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:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169430-61e80f247b7d4.png\" alt=\"Conversione di React.createClass in React.Component\" \/>I file del tutorial di GitHub per la conversione da React.createClass a React.Component<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte di registrazione:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/wholesomecode.ltd\" class=\"external external_icon\">wholesomecode.ltd<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nel mio ultimo articolo ho parlato dell&#8217;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 cl&#8230;<\/p>\n","protected":false},"author":1,"featured_media":224207,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[918,896,720,844],"tags":[1168],"class_list":["post-228877","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-altro","category-codice","category-sviluppatore","category-tutorial","tag-affiai-it"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/228877","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/comments?post=228877"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/228877\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media\/224207"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media?parent=228877"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/categories?post=228877"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/tags?post=228877"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}