Сегодня мы публикуем перевод очередного занятия учебного курса по React. Оно посвящено компонентам, основанным на классах. Такие компоненты создают с использованием ключевого слова class.
→ Часть 1: обзор курса, причины популярности React, ReactDOM и JSX
→ Часть 2: функциональные компоненты
→ Часть 3: файлы компонентов, структура проектов
→ Часть 4: родительские и дочерние компоненты
→ Часть 5: начало работы над TODO-приложением, основы стилизации
→ Часть 6: о некоторых особенностях курса, JSX и JavaScript
→ Часть 7: встроенные стили
→ Часть 8: продолжение работы над TODO-приложением, знакомство со свойствами компонентов
→ Часть 9: свойства компонентов
→ Часть 10: практикум по работе со свойствами компонентов и стилизации
→ Часть 11: динамическое формирование разметки и метод массивов map
→ Часть 12: практикум, третий этап работы над TODO-приложениемЗанятие 24. Компоненты, основанные на классах
Если вы, до того, как начали осваивать этот учебный курс, изучали React по материалам каких-то других курсов, у вас может возникнуть вопрос по поводу того, что здесь мы пользуемся функциональными компонентами. Дело в том, что во многих других курсах эта тема либо не освещается, либо о функциональных компонентах говорят как о чём-то таком, в чём нет особой необходимости. Некоторые авторы идут ещё дальше и говорят о том, что функциональные компоненты лучше не использовать, отдавая предпочтение компонентам, основанным на классах. Это, по их мнению, избавляет программиста от ненужной нагрузки. Я же полагаю, что любому, кто изучает React, полезно будет увидеть полную картину и узнать о популярных в наши дни подходах по работе с компонентами. В частности, сейчас актуально направление, в соответствии с которым везде, где это возможно, используют функциональные компоненты, а компоненты, основанные на классах — лишь там, где они действительно необходимы. При этом надо отметить, что всё это — лишь рекомендации. Каждый разработчик сам решает как именно он будет конструировать свои приложения.
Когда я веду курсы по React, я предпочитаю начинать с функциональных компонентов, так как функции — понятные конструкции. Одного взгляда на функциональный компонент достаточно для того, чтобы понять, какие именно действия он выполняет. Скажем, вот код функционального компонента, который представляет собой обычную функцию, возвращающую элемент<div>
, содержащий элемент<h1>
с неким текстом.function App() {
return (
<div>
<h1>Code goes here</h1>
</div>
)
}
Но, по мере того, как мы углубляемся в изучение React, знакомимся с его возможностями, оказывается, что функциональные компоненты не способны предложить нам всё то, что может понадобиться нам от React-компонентов. Поэтому сегодня мы поговорим о компонентах, основанных на классах. А именно, начнём с создания компонента, основанного на классе, который выполняет те же действия, что и вышеприведённый функциональный компонент. А на следующих занятиях мы коснёмся тех дополнительных возможностей, которые дают нам компоненты, основанные на классах. В частности, речь идёт о возможности работы с состоянием компонентов и с методами их жизненного цикла.
Преобразуем функциональный компонент в компонент, основанный на классе. Если вы не особенно хорошо знакомы с ключевым словомclass
, появившемся в ES6, и с возможностями, которые оно открывает перед разработчиками, рекомендуется уделить некоторое время на то, чтобы познакомиться с классами поближе.
Описание компонента, основанного на классах, начинается с ключевого словаclass
. Затем идёт имя компонента, составляемое по тем же правилам, что и имена функциональных компонентов. При этом после конструкции наподобиеclass App
будет идти не нечто вроде фигурной скобки, а конструкция видаextends React.Component
. После неё ставится пара фигурных скобок, в которых будет описано тело класса.
Классы в JavaScript представляют собой надстройку над традиционной моделью прототипного наследования. Сущность конструкцииclass App extends React.Component
сводится к тому, что мы объявляем новый класс и указываем на то, что его прототипом должен бытьReact.Component
. Наличие у нашего компонента этого прототипа позволяет пользоваться в этом компоненте всеми теми полезными возможностями, которые имеются вReact.Component
.
Итак, на данном этапе работы над компонентом, основанном на классах, его код выглядит так:class App extends React.Component {
}
У компонента, основанного на классах, должен быть, по меньшей мере, один метод. Это — метод
render()
. Данный метод должен возвращать то же самое, что мы обычно возвращаем из функциональных компонентов. Вот как выглядит полный код компонента, основанного на классах, реализующего те же возможности, что и вышеприведённый функциональный компонент.class App extends React.Component {
render() {
return (
<div>
<h1>Code goes here</h1>
</div>
)
}
}
Работают с компонентами, основанными на классах так же, как с функциональными компонентами. То есть, в нашем случае достаточно заменить код функционального компонента на новый код и приложение будет работать так же, как и прежде.
Поговорим о методеrender()
. Если, перед формированием элементов, возвращаемых этим методом, нужно выполнить некие вычисления, их выполняют именно в этом методе, перед командойreturn
. То есть, если у вас есть некий код, определяющий порядок формирования визуального представления компонента, этот код нужно поместить в методrender
. Например, тут можно выполнить настройку стилей в том случае, если вы пользуетесь встроенными стилями. Здесь же будет и код, реализующий механизм условного рендеринга, и другие подобные конструкции.
Если вы знакомы с классами, вы можете создать собственный метод и разместить код, готовящий компонент к визуализации, в нём, после чего вызвать этот метод в методеrender
. Выглядит это так:class App extends React.Component {
yourMethodHere() {
}
render() {
const style = this.yourMethodHere()
return (
<div>
<h1>Code goes here</h1>
</div>
)
}
}
А именно, тут мы исходим из предположения о том, что в методе
yourMethodHere()
производится формирование стилей, а то, что он возвращает, записывается в константуstyle
, объявленную в методеrender()
. Обратите внимание на то, что для обращения к нашему собственному методу используется ключевое словоthis
. Позже мы поговорим об особенностях этого ключевого слова, но пока остановимся на представленной здесь конструкции.
Теперь поговорим о том, как в компонентах, основанных на классах, работать со свойствами, передаваемыми им при создании их экземпляров.
При использовании функциональных компонентов мы объявляли соответствующую функцию с параметромprops
, представляющим собой объект, в который попадало то, что передавалось компоненту при создании его экземпляра. Выглядит это так:function App(props) {
return (
<div>
<h1>{props.whatever}</h1>
</div>
)
}
При работе с компонентом, основанном на классе, то же самое выглядит так:
class App extends React.Component {
render() {
return (
<div>
<h1>{this.props.whatever}</h1>
</div>
)
}
}
Итоги
Как уже было сказано, компоненты, основанные на классах, дают разработчику множество возможностей. Об этих возможностях мы ещё поговорим. А сейчас можете поэкспериментировать с тем, что вы узнали сегодня и подготовиться к практическому занятию по компонентам, которые основаны на классах.
JavaScript