{"id":228022,"date":"2022-10-12T18:20:00","date_gmt":"2022-10-12T15:20:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=228022"},"modified":"2022-11-09T00:18:06","modified_gmt":"2022-11-08T21:18:06","slug":"konvertera-react-createclass-till-react-component","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/sv\/konvertera-react-createclass-till-react-component\/","title":{"rendered":"Konvertera React.createClass till React.Component"},"content":{"rendered":"\n<p>I min <a href=\"https:\/\/wholesomecode.ltd\/blog\/broken-react-createclass-component-lets-fix-it\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">f\u00f6rra artikel pratade jag om att patcha \u00e4ldre versioner av React f\u00f6r att fungera i en modern milj\u00f6<\/a>. I den h\u00e4r artikeln g\u00e5r jag ett steg l\u00e4ngre och ger en steg-f\u00f6r-steg-guide f\u00f6r att uppgradera en klassisk React-komponent till en modern, genom att byta ut <code>React.createClass<\/code>s\u00e4ttet att g\u00f6ra saker p\u00e5 till den moderna och f\u00f6redragna <code>React.Component<\/code>metoden.<\/p>\n<p>Filerna vi beh\u00f6ver finns i mapparna &#8217;Original&#8217; och &#8217;Slutlig&#8217; i komponentkatalogen i den medf\u00f6ljande GitHub-l\u00f6sningen.<\/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\">F\u00e5 handledningsfiler fr\u00e5n GitHub<\/a><\/p>\n<p>\u00c5terigen arbetar med komponenten <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\">fr\u00e5n Sony An<\/a> (tillg\u00e4nglig <a href=\"https:\/\/www.npmjs.com\/package\/react-checkbox-list\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\"><code>react-checkbox-list<\/code>fr\u00e5n npm<\/a> ). Denna guide visar dig steg f\u00f6r steg hur du byter ut strukturen och metoderna f\u00f6r en klassisk <code>React.createClass<\/code>komponent till en modern <code>React.Component<\/code>.<\/p>\n<p>Fr\u00e5n och med <code>.jsx<\/code>filen i <code>react-checkbox-list<\/code>l\u00f6sningen kommer vi f\u00f6rst att ta bort <code>.js<\/code>filen och byta namn p\u00e5 den till <code>.js<\/code>eftersom <code>.jsx<\/code>filer inte l\u00e4ngre beh\u00f6ver heta annorlunda.<\/p>\n<p>Det ger oss f\u00f6ljande startkod:<\/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>Konvertera komponenten<\/h2>\n<p>N\u00e4r vi f\u00f6rs\u00f6ker ladda den h\u00e4r koden \u00e4r det f\u00f6rsta felet vi f\u00e5r<code>Uncaught Error: Module build failed: SyntaxError: The @jsx React.DOM pragma has been deprecated as of React 0.12<\/code><\/p>\n<p>Of\u00e5ngat fel: Modulbygget misslyckades: SyntaxError: <a href=\"https:\/\/hashnode.com\/@jsx\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@jsx<\/a> React.DOM-pragman har fasats ut fr\u00e5n och med React 0.12<\/p>\n<p>Det \u00e4r enkelt att r\u00e4tta till detta. Ta bara bort raden <code>\/** @jsx React.DOM *\/<\/code>fr\u00e5n toppen av dokumentet.<\/p>\n<p>Vi f\u00e5r nu samma fel som <code>Uncaught TypeError: Cannot read property 'array' of undefined<\/code>i <a href=\"https:\/\/wholesomecode.ltd\/blog\/broken-react-createclass-component-lets-fix-it\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">patchhandledningen<\/a> <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 external_icon\">.<\/a> Detta beror p\u00e5 att React.propTypes fasades ut i React version 15.50, s\u00e5 enligt den handledningen, forts\u00e4tt och installera PropTypes-paketet med kommandot via npm. Vi kommer att importera detta till v\u00e5rt paket senare.<\/p>\n<pre><code>npm install --save prop-types\n<\/code><\/pre>\n<p>Det som f\u00f6ljer nu \u00e4r en fullst\u00e4ndig \u00f6versyn av kodbasen, s\u00e5 vi kan inte uppdatera och fixa ett fel som vi kan ha gjort tidigare, s\u00e5 vi kommer inte att veta om det har fungerat f\u00f6rr\u00e4n i slutet. Sp\u00e4nn fast!<\/p>\n<p>L\u00e5t oss b\u00f6rja med att ers\u00e4tta <code>React.createClass<\/code>funktionen genom att deklarera en ny <code>React.Component<\/code>. \u00c4ndra v\u00e5r kod s\u00e5 att den ser ut s\u00e5 h\u00e4r:<\/p>\n<pre><code>'use strict';\nimport React from 'react';\n\nclass CheckBoxList extends React.Component {\n...\n}\n<\/code><\/pre>\n<p>Observera att vi har gjort n\u00e5gra saker h\u00e4r:<\/p>\n<ul>\n<li>Tog bort den inledande JSX-kommentaren<\/li>\n<li>\u00c4ndrad deklarationstyp fr\u00e5n <code>var React =...<\/code>till <code>import React from 'react';<\/code>detta \u00e4r det moderna s\u00e4ttet att g\u00f6ra deklarationer i React.<\/li>\n<li>Vi deklarerar nu en ny klass av <code>CheckBoxList<\/code>ist\u00e4llet f\u00f6r att exportera en funktion.<\/li>\n<li>P\u00e5 grund av syntaxen f\u00f6r objektet som nu \u00e4r innesluten inom parentes <code>{...}<\/code>m\u00e5ste vi ta bort st\u00e4ngningen<code>);<\/code><\/li>\n<\/ul>\n<p>Men den h\u00e4r nya klassen saknar nu ett s\u00e4tt att exportera den s\u00e5 att andra komponenter kan anv\u00e4nda den, s\u00e5 l\u00e5t oss l\u00e4gga till en exportdeklaration l\u00e4ngst ner i den koden.<\/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>I v\u00e5r ursprungliga kod hanterar den f\u00f6rsta kodraden i funktionen var <code>displayName: 'CheckBoxList',<\/code>v\u00e5r export nu detta, s\u00e5 vi kan ta bort den koden helt.<\/p>\n<p>N\u00e4sta rad ner f\u00f6rklarar att <code>propTypes<\/code>dessa nu sitter utanf\u00f6r klassen och beh\u00f6ver det <code>PropTypes<\/code>beroende som vi lagt till via npm. L\u00e5t oss l\u00e4gga till det i v\u00e5ra importer och skriva PropTypes s\u00e5 h\u00e4r:<\/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>D\u00e4refter deklareras tillst\u00e5ndet via metoden <code>getInitialState<\/code>d\u00e4r <code>React.Component<\/code>vi st\u00e4ller in v\u00e5rt initiala tillst\u00e5nd med en konstruktor. L\u00e4gg till f\u00f6ljande kod i v\u00e5rt bygge:<\/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>D\u00e4r g\u00e5r vi, som st\u00e4ller in komponentens tillst\u00e5nd, men h\u00e5ll ut, vi har faktiskt inte ber\u00e4ttat f\u00f6r den var den ska f\u00e5 sitt tillst\u00e5nd ifr\u00e5n. Det \u00e4r d\u00e4r som <code>componentWillMount<\/code>kommer v\u00e4l till pass.<\/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>En viktig sak att notera \u00e4r att de inre metoderna f\u00f6r <code>React.Component<\/code>inte slutar med kommatecken (<code>,<\/code>), s\u00e5 se till att alla metoder du l\u00e4gger till i komponenten inte slutar med komma!<\/p>\n<p>N\u00e4sta upp, l\u00e5t oss l\u00e4gga till renderingsfunktionen igen. Detta \u00e4r f\u00f6rmodligen den enklaste delen, den \u00e4r n\u00e4stan densamma, med nyckelskillnaden att vi \u00e4ndrar <code>render: function() {<\/code>till bara <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>F\u00f6r att h\u00e5lla den h\u00e4r handledningen till punkten kommer jag inte att konvertera de tv\u00e5 metoderna <code>reset<\/code>och <code>checkAll<\/code>hur begreppen som anv\u00e4nds f\u00f6r porten av <code>handleItemChange<\/code>metod\u00e4pplet till b\u00e5da, s\u00e5 f\u00f6rs\u00f6k g\u00e4rna med dem sj\u00e4lv.<\/p>\n<p>F\u00f6r att migrera <code>handleItemChange<\/code>metoden m\u00e5ste vi f\u00f6rst ta bort det avslutande kommatecken (<code>,<\/code>) och \u00e4ndra funktionsdeklarationstypen fr\u00e5n <code>handleItemChange: function(e) {<\/code>att <code>handleItemChange( e) {<\/code>se till att vi fortfarande skickar <code>e<\/code>in som h\u00e4ndelseparameter.<\/p>\n<p>L\u00e5t oss l\u00e4gga till det ovanf\u00f6r v\u00e5r renderingsmetod.<\/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>V\u00e5r komponent kommer nu att renderas, men den kommer inte att fungera. N\u00e4r du f\u00f6rs\u00f6ker klicka p\u00e5 en kryssruta f\u00e5r du felet <code>Uncaught TypeError: Cannot read property 'state' of undefined<\/code>.<\/p>\n<p>Uncaught TypeError: Kan inte l\u00e4sa egenskapen &quot;state&quot; f\u00f6r odefinierad<\/p>\n<p>Detta beror p\u00e5 att i v\u00e5r <code>handleItemChange<\/code>metod, d\u00e4r vi f\u00f6rs\u00f6ker komma \u00e5t staten, <code>this<\/code>\u00e4r odefinierad. F\u00f6r att fixa detta m\u00e5ste vi binda v\u00e5r funktion till <code>this<\/code>genom att l\u00e4gga till f\u00f6ljande rad i v\u00e5r konstruktor: <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>Och d\u00e4r har vi det, v\u00e5r nykonverterade React-komponent i aktion.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169430-61e80f22b2772.gif\" alt=\"Konvertera React.createClass till React.Component\" \/>React.createClass till React.Component<\/p>\n<h2>Handlednings k\u00e4llkod<\/h2>\n<p>Du kan <a href=\"https:\/\/github.com\/wholesomecode\/Tutorial-Convert-React-createClass-to-React-Component\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ladda ner k\u00e4llkoden f\u00f6r den ursprungliga och slutliga versionen av komponenten p\u00e5 GitHub<\/a>. Pluginet inneh\u00e5ller ett WordPress Gutenberg-block som du kan anv\u00e4nda f\u00f6r att leka med koden, med tre filer som du kan ta bort i f\u00f6rekommande fall:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169430-61e80f247b7d4.png\" alt=\"Konvertera React.createClass till React.Component\" \/>GitHub Tutorial-filer f\u00f6r React.createClass till React.Component-konverteringen<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Inspelningsk\u00e4lla:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/wholesomecode.ltd\" class=\"external external_icon\">wholesomecode.ltd<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I min f\u00f6rra artikel pratade jag om att patcha \u00e4ldre versioner av React f\u00f6r att fungera i en modern milj\u00f6. I den h\u00e4r artikeln g\u00e5r jag ett steg l\u00e4ngre och ger en steg-f\u00f6r-steg-guide f\u00f6r att uppgradera en kl&#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":[848,901,922,724],"tags":[1173],"class_list":["post-228022","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-handledningar","category-koda","category-oevrig","category-utvecklaren","tag-affiai-sv"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/228022","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/comments?post=228022"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/228022\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media\/224207"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media?parent=228022"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/categories?post=228022"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/tags?post=228022"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}