Преобразование React.createClass в React.Component
В своей прошлой статье я рассказывал о патчинге старых версий React для работы в современной среде. В этой статье я пойду еще дальше и дам пошаговое руководство по обновлению классического компонента React до современного, заменив React.createClass
способ ведения дел на современный и предпочтительный React.Component
метод.
Нужные нам файлы будут находиться в папках «Исходный» и «Конечный» каталога компонентов в сопутствующем решении 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
Uncaught Error: сбой сборки модуля: 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: невозможно прочитать состояние свойства неопределенного
Это потому, что в нашем 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