W moim ostatnim artykule mówiłem o łataniu starszych wersji Reacta, aby działały w nowoczesnym środowisku. W tym artykule idę krok po kroku i krok po kroku, jak uaktualnić klasyczny komponent React do nowoczesnego, zmieniając React.createClass
sposób robienia rzeczy na nowoczesną i preferowaną React.Component
metodę.
Potrzebne nam pliki będą znajdować się w folderach „Original" i „Final” katalogu komponentów w towarzyszącym rozwiązaniu GitHub.
Pobierz pliki samouczka z GitHub
Znowu praca z komponentem [react-checkbox-list](https://github.com/sonyan/react-checkbox-list)
Sony An (dostępny jak react-checkbox-list
na npm ). Ten przewodnik pokazuje krok po kroku, jak zastąpić konstrukcję i metody klasycznego React.createClass
komponentu nowoczesnym React.Component
.
Zaczynając od .jsx
pliku w react-checkbox-list
rozwiązaniu, najpierw usuniemy .js
plik i zmienimy jego nazwę, .js
ponieważ .jsx
pliki nie muszą już mieć innych nazw.
To daje nam następujący kod startowy:
Konwersja komponentu
Podczas próby załadowania tego kodu pierwszym błędem, jaki otrzymujemy, jestUncaught Error: Module build failed: SyntaxError: The @jsx React.DOM pragma has been deprecated as of React 0.12
Nieprzechwycony błąd: Budowa modułu nie powiodła się: SyntaxError: Pragma @jsx React.DOM została uznana za przestarzałą w React 0.12
Łatwo to naprawić. Po prostu usuń linię /** @jsx React.DOM */
z góry dokumentu.
Otrzymujemy teraz ten Uncaught TypeError: Cannot read property 'array' of undefined
sam błąd, co w samouczku dotyczącym łatania. Dzieje się tak dlatego, że React.propTypes był przestarzały w wersji React 15.50, więc zgodnie z tym samouczkiem zainstaluj pakiet PropTypes za pomocą polecenia przez npm. Zaimportujemy to później do naszego pakietu.[React.createClass](https://wholesomecode.ltd/blog/broken-react-createclass-component-lets-fix-it/)
npm install --save prop-types
To, co następuje teraz, to kompletna przebudowa bazy kodu, więc nie możemy odświeżyć i naprawić błędu, jak mogliśmy to zrobić wcześniej, więc nie będziemy wiedzieć, czy zadziałało to do samego końca. Brać się do rzeczy!
Zacznijmy od zastąpienia React.createClass
funkcji przez zadeklarowanie nowego React.Component
. Zmień nasz kod tak, aby wyglądał następująco:
'use strict';
import React from 'react';
class CheckBoxList extends React.Component {
...
}
Zauważ, że zrobiliśmy tutaj kilka rzeczy:
- Usunięto otwierający komentarz JSX
- Zmieniony typ deklaracji z
var React =...
naimport React from 'react';
ten to nowoczesny sposób składania deklaracji w React. - Teraz deklarujemy nową klasę
CheckBoxList
, zamiast eksportować funkcję. - Ze względu na składnię obiektu, który jest teraz ujęty w nawias
{...}
, musimy usunąć zamknięcie);
Jednak tej nowej klasie brakuje teraz sposobu na wyeksportowanie jej, aby inne komponenty mogły z niej korzystać, więc dodajmy deklarację eksportu na dole tego kodu.
'use strict';
import React from 'react';
class CheckBoxList extends React.Component {
...
}
export default CheckBoxList;
W naszym oryginalnym kodzie, pierwszy wiersz kodu w funkcji był displayName: 'CheckBoxList',
naszym eksportem, teraz obsługuje to, więc możemy całkowicie usunąć ten kod.
Następna linia niżej deklaruje, że propTypes
te znajdują się teraz poza klasą i potrzebują PropTypes
zależności, którą dodaliśmy przez npm. Dodajmy to do naszego importu i napiszmy PropTypes w ten sposób:
'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;
Następnie stan jest deklarowany za pomocą metody, getInitialState
w React.Component
której ustawiamy nasz stan początkowy za pomocą konstruktora. Dodaj następujący kod do naszej kompilacji:
...
class CheckBoxList extends React.Component {
constructor( props) {
super( props );
this.state = {
data: [],
}
}
...
}
...
No i zaczynamy, ustawiamy stan komponentu, ale poczekaj, nie powiedzieliśmy mu, skąd wziąć jego stan. To componentWillMount
się przydaje.
...
class CheckBoxList extends React.Component {
constructor( props) {
super( props );
this.state = {
data: [],
}
}
componentWillMount() {
this.setState({
data: this.props.defaultData,
});
}
...
}
...
Kluczową rzeczą do zapamiętania jest to, że wewnętrzne metody React.Component
nie kończą się przecinkami (,
), więc upewnij się, że metody dodane do komponentu nie kończą się przecinkiem!
Następnie dodajmy z powrotem funkcję render. To prawdopodobnie najłatwiejsza część, jest prawie taka sama, z kluczową różnicą, którą zmieniamy render: function() {
na just render() {
.
Aby utrzymać ten samouczek na temat, nie będę konwertować dwóch metod reset
i checkAll
pojęć używanych do przeniesienia metody handleItemChange
apple na obie, więc możesz spróbować samemu.
Aby przeprowadzić migrację handleItemChange
metody, najpierw musimy usunąć zamykający przecinek (,
) i zmienić typ deklaracji funkcji z handleItemChange: function(e) {
na handleItemChange( e) {
upewniając się, że nadal przekazujemy e
jako parametr zdarzenia.
Dodajmy to powyżej naszej metody renderowania.
...
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);
}
}
...
}
...
Nasz komponent będzie się teraz renderował, ale nie będzie działał. Gdy spróbujesz kliknąć pole wyboru, pojawi się błąd Uncaught TypeError: Cannot read property 'state' of undefined
.
Nieprzechwycony błąd typu: nie można odczytać właściwości „stan” niezdefiniowanej
Dzieje się tak, ponieważ w naszej handleItemChange
metodzie, w której próbujemy uzyskać dostęp do stanu, this
jest on niezdefiniowany. Aby to naprawić, musimy powiązać naszą funkcję this
, dodając następujący wiersz do naszego konstruktora: this.handleItemChange = this.handleItemChange.bind( this );
.
...
class CheckBoxList extends React.Component {
constructor( props) {
super( props );
this.state = {
data: [],
}
this.handleItemChange = this.handleItemChange.bind( this );
}
...
}
...
I oto mamy to, nasz nowo przekonwertowany komponent React w akcji.
React.createClass do React.Component
Kod źródłowy samouczka
Możesz pobrać kod źródłowy oryginalnej i ostatecznej wersji komponentu z serwisu GitHub. Wtyczka zawiera blok WordPress Gutenberg, którego możesz użyć do zabawy z kodem, z trzema plikami, które możesz usunąć, jeśli dotyczy:
Pliki samouczka GitHub dla React.createClass do konwersji React.Component