Перетворення React.createClass на React.Component
У своїй останній статті я розповідав про виправлення старих версій React для роботи в сучасному середовищі. У цій статті я йду ще далі та даю покроковий посібник із оновлення класичного компонента React до сучасного, змінивши React.createClass
спосіб виконання завдань на сучасний і бажаний React.Component
метод.
Файли, які нам потрібні, будуть у папках «Original» і «Final» каталогу компонентів у супровідному рішенні GitHub.
Отримайте навчальні файли з GitHub
Знову працюємо з компонентом [react-checkbox-list](https://github.com/sonyan/react-checkbox-list)
Sony An (доступний як react-checkbox-list
на npm ). У цьому посібнику крок за кроком показано, як замінити структуру та методи класичного React.createClass
компонента на сучасний React.Component
.
Починаючи з .jsx
файлу в react-checkbox-list
рішенні, ми спочатку видалимо .js
файл і перейменуємо його на .js
, оскільки .jsx
файли більше не повинні називатися інакше.
Це дає нам наступний початковий код:
Перетворення компонента
Під час спроби завантажити цей код перша помилка, яку ми отримуємо:Uncaught Error: Module build failed: SyntaxError: The @jsx React.DOM pragma has been deprecated as of React 0.12
Невловлена помилка: не вдалося створити модуль: SyntaxError: Прагма @jsx React.DOM застаріла з React 0.12
Виправити це досить просто. Просто приберіть рядок /** @jsx React.DOM */
у верхній частині документа.
Тепер ми отримуємо таку Uncaught TypeError: Cannot read property 'array' of undefined
саму помилку, як у посібнику з виправлення. Це пояснюється тим, що React.propTypes застарів у React версії 15.50, тому, згідно з цим підручником, встановіть пакет PropTypes за допомогою команди через npm. Ми імпортуємо це в наш пакет пізніше.[React.createClass](https://wholesomecode.ltd/blog/broken-react-createclass-component-lets-fix-it/)
npm install --save prop-types
Тепер слід повністю переробити кодову базу, тому ми не можемо оновити та виправити помилку, як ми, можливо, робили раніше, тому ми не знатимемо, чи вона спрацювала до самого кінця. Пристебніться!
Давайте почнемо із заміни React.createClass
функції на оголошення нового React.Component
. Змініть наш код, щоб він виглядав так:
'use strict';
import React from 'react';
class CheckBoxList extends React.Component {
...
}
Зверніть увагу, що тут ми зробили кілька речей:
- Видалено початковий коментар JSX
- Змінено тип оголошення з
var React =...
наimport React from 'react';
це сучасний спосіб створення оголошень у React. - Тепер ми оголошуємо новий клас
CheckBoxList
замість експорту функції. - Через синтаксис об’єкта, який зараз узятий у дужки
{...}
, нам потрібно відкинути закриття);
Однак цей новий клас тепер не має способу його експорту, щоб інші компоненти могли його використовувати, тому давайте додамо декларацію експорту внизу цього коду.
'use strict';
import React from 'react';
class CheckBoxList extends React.Component {
...
}
export default CheckBoxList;
У нашому оригінальному коді перший рядок коду у функції був displayName: 'CheckBoxList',
нашим експортом, який тепер обробляє це, тому ми можемо повністю видалити цей код.
Наступний рядок оголошує, що propTypes
ці тепер знаходяться поза класом і потребують PropTypes
залежності, яку ми додали через npm. Давайте додамо це до нашого імпорту та напишемо PropTypes так:
'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;
Далі стан оголошується за допомогою методу, getInitialState
за допомогою якого React.Component
ми встановлюємо початковий стан за допомогою конструктора. Додайте наступний код у нашу збірку:
...
class CheckBoxList extends React.Component {
constructor( props) {
super( props );
this.state = {
data: [],
}
}
...
}
...
Отже, це встановлює стан компонента, але чекайте, ми насправді не сказали йому, звідки отримати свій стан. Ось де componentWillMount
стане в нагоді.
...
class CheckBoxList extends React.Component {
constructor( props) {
super( props );
this.state = {
data: [],
}
}
componentWillMount() {
this.setState({
data: this.props.defaultData,
});
}
...
}
...
Важливо зауважити, що внутрішні методи React.Component
не закінчуються комами (,
), тому переконайтеся, що всі методи, які ви додаєте до компонента, не закінчуються комами!
Далі, давайте знову додамо функцію рендерингу. Це, мабуть, найпростіша частина, вона майже така сама, з тією ключовою різницею, що ми змінюємо render: function() {
її на просто render() {
.
Щоб зберегти зміст цього підручника, я не буду перетворювати ці два методи reset
, checkAll
однак концепції, використані для перенесення методу handleItemChange
apple, підходять для обох, тож не соромтеся спробувати їх самостійно.
Щоб перенести handleItemChange
метод, нам спочатку потрібно видалити кінцеву кому (,
) і змінити тип оголошення функції з handleItemChange: function(e) {
на handleItemChange( e) {
переконавшись, що ми все ще передаємо e
як параметр події.
Додамо це над нашим методом візуалізації.
...
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);
}
}
...
}
...
Тепер наш компонент відтворюватиметься, але не працюватиме. Коли ви спробуєте натиснути прапорець, ви отримаєте повідомлення про помилку Uncaught TypeError: Cannot read property 'state' of undefined
.
Uncaught TypeError: неможливо прочитати властивість ‘state’ невизначеного
Це тому, що в нашому handleItemChange
методі, де ми намагаємося отримати доступ до стану, this
не визначено. Щоб виправити це, нам потрібно прив’язати нашу функцію this
, додавши такий рядок у наш конструктор: this.handleItemChange = this.handleItemChange.bind( this );
.
...
class CheckBoxList extends React.Component {
constructor( props) {
super( props );
this.state = {
data: [],
}
this.handleItemChange = this.handleItemChange.bind( this );
}
...
}
...
І ось він, наш щойно перетворений компонент React у дії.
React.createClass до React.Component
Вихідний код підручника
Ви можете завантажити вихідний код оригінальної та остаточної версії компонента на GitHub. Плагін містить блок WordPress Gutenberg, який можна використовувати, щоб пограти з кодом, із трьома файлами, які можна видалити, якщо це необхідно:
Файли посібників GitHub для перетворення React.createClass у React.Component