Створення власного блоку Гутенберга – Частина 7: Створення власних користувацьких компонентів
Поки що в цій серії посібників ми написали весь код у registerBlockType()
функції edit
. Цілком можливо, і часто рекомендується натомість призначити редагування окремому компоненту. Роблячи це, ми можемо використовувати такі функції, як стан компонентів і методи життєвого циклу. Він також набагато чистіший, читабельніший і містить багаторазовий код!
Якщо ви не знайомі зі створенням компонентів React або методами стану та життєвого циклу, я рекомендую спочатку прочитати офіційний посібник React на цю тему.
Визначення компонента класу дляedit
Ви можете визначити компонент або як функцію, або як клас. За допомогою компонента класу ви можете використовувати такі функції, як, наприклад, методи стану та життєвого циклу. Однак у новіших версіях React (16+) ви можете використовувати хуки React для симуляції методів стану та життєвого циклу всередині функціональних компонентів. Але в цьому підручнику ми зосередимося на створенні компонента класу. Те, що ми створили досі в цій серії, «вбудовані» в registerBlockType()
for edit
і save
, є функціональними компонентами.
Для визначення компонента класу ми розширюємо WordPress’ Component
(у wp.element
пакеті), так само, як ви розширюєте компонент класу до React.Component
.
Майте на увазі, що ваш компонент класу повинен містити функцію render()
. І через те, як працює Javascript, ваш клас має бути визначений перед вашим registerBlockType()
викликом (напишіть свій компонент класу спочатку у файл, а збережіть registerBlockType()
його після нього. Пізніше в цьому дописі ми дізнаємося, як відокремлювати компоненти в окремі файли, експортувати та включати їх).
Коротше кажучи так:
Реквізити з edit
автоматично застосовуються до нашого компонента. Не забувайте, що компонент класу, який вам потрібно посилатися на props за допомогою this.props
. У ядрі WordPress Gutenberg зазвичай використовують окремі компоненти для edit
функцій, оскільки вони найчастіше містять набагато більше коду. Функцію save
часто можна залишити, registerBlockType()
якщо вона також не містить багато коду.
Зробивши це, тепер ви можете написати свій компонент так само, як і з React. Ви можете додавати функції, конструктор, методи стану та життєвого циклу.
Це код, який ми отримали на останньому кроці, перетворений на компонент класу:
Якщо ви деструктурували attributes
та setAttributes
використовували властивості, як це зробили ми, все, що вам потрібно змінити під час переходу до окремого компонента класу, це змінити один рядок; #9
від props
до this.props
. Увесь код працюватиме так само, як і раніше, без жодних виправлень. У цьому краса деструктуризації. Якщо ви не деструктурували його й посилалися, наприклад props.attributes
, безпосередньо, вам потрібно було б додати this.
перед усіма окремими посиланнями на attributes
та setAttributes
всюди.
Давайте почнемо робити те, що ми зараз можемо робити з компонентом класу!
Визначення функцій іthis
Звичайно, так, ви можете визначити функції з edit
компонента функції перед викликом return
. Але особисто я завжди вважав за краще розділяти функціональність за логікою. Я вважаю, що краще відокремити функції для логіки та інших цілей поза функцією, яка відповідає за рендеринг виводу. Деякі люди також вважають за краще викликати функції в подіях, замість того, щоб робити їх вбудованими, як ми робили досі (робимо, setAttributes()
наприклад onChange
).
На даний момент у нашому коді є дві речі, які було б корисно перенести до функцій; InspectorControls
і BlockControls
. Це значно скоротить return
наш код і полегшить читання.
Ми визначаємо дві функції, які повертають весь InspectorControls
блок і весь BlockControls
блок. Використовуючи функції зі стрілками (functionName =() => { ... }
), ми маємо повний доступ до this
для отримання реквізитів. Якщо ви не виконали останню частину кроку 1 – налаштування Babel із найновішим синтаксисом, ви отримаєте помилки компіляції. Вам доведеться вдатися до створення конструктора та зв’язування this
для кожної функції. Ви можете прочитати більше про обробку this
на початку сторінки поширених запитань React.
Також пам’ятайте, що оскільки ми зараз у класі, вам потрібно викликати всі його функції за допомогою this.
попереду.
Зверніть увагу, що я виключив фактичний вміст InspectorControls
і BlockControls
щоб зберегти код коротшим. Нічого в їх коді не потрібно змінювати.
Ми також використовуємо той факт, що return
оператор також може повертати масив. Усе в масиві буде відображено як зазвичай у тому порядку, у якому вони розташовані. Це полегшує нам виклик функцій безпосередньо в return
операторі.
Ви, очевидно, також можете визначити методи життєвого циклу, такі як componentDidMount()
. Немає різниці в тому, як це робити в компонентах Gutenberg, ніж у React.
Конструктор і стан використання
Давайте спробуємо реалізувати стан у нашому компоненті. Пам’ятайте, що стан – це лише те, що тимчасово зберігається в нашому компоненті класу і ніде не зберігається – наприклад, в атрибутах. Це просто для того, щоб контролювати – ну – стан вашого компонента. Загальне використання стану полягає у використанні стану як позначки стану під час очікування повернення асинхронного виклику, збереження оцінки чогось тимчасового перед збереженням в атрибуті або впровадження блокових «режимів попереднього перегляду/редагування».
Ви посилаєтеся на стан і стан оновлення так само, як у React; з this.state
і setState()
. Зазвичай ви ініціалізуєте стан у конструкторі. А щодо визначення конструктора – це точно так само, як у React – не забудьте також передати props
і зробити super(props)
. Коротко:
class FirstBlockEdit extends Component {
constructor(props) {
super(props);
this.state = {
example: 1
}
}
render() {
this.setState({ example: 2 });
console.log(this.state.example);
...
Перемикач редагування/попереднього перегляду режиму блокування
Давайте використаємо те, що ми дізналися на попередньому кроці в панелях інструментів, щоб створити «перемикач режимів» для нашого блоку. Ми реалізуємо панель інструментів із кнопкою, яка перемикає стан між режимом попереднього перегляду та редагування. У режимі редагування блок отримує два компоненти RichText, як зазвичай. Але під час переходу в режим попереднього перегляду ми вимкнули редагування та рендеринг блокового виводу.
Спочатку ми створюємо конструктор і встановлюємо стан з однією булевою властивістю; editMode
який починається як true
. Це super(props)
необхідно під час визначення конструктора в компоненті React на основі класу.
class FirstBlockEdit extends Component {
constructor(props) {
super(props);
this.state = {
editMode: true
}
}
...
У нашій функції для виведення панелей інструментів ми змінюємо спеціальну кнопку, яку ми створили раніше (яка виникає лише console.log
при натисканні на неї). У його onClick
властивості ми викликаємо поточне логічне значення setState()
та заперечуємо його. editMode
Щоб користувачеві було легше зрозуміти, ми також перемикаємося між значком кнопки та міткою. Наприклад, коли режим попереднього перегляду активний, кнопка відображає мітку «Редагувати» та піктограму олівця, яка зазвичай прийнятна для редагування.
І, нарешті, в основному методі візуалізації для нашого блоку ми можемо робити те, що хочемо. Ця частина дійсно залежить від вас – ви робите те саме, що ми робили з міткою та піктограмою на кнопці вище. Ми додаємо два блоки виводу: один, якщо this.state.editMode
є true
(це повинні бути звичайні редаговані RichText
компоненти), а інший, якщо це false
.
Як приклад я використовую два компоненти WordPress із wp.components
; Placeholder
і Disabled
для режиму попереднього перегляду. Компонент Placeholder
розміщує ваш блок у гарній сірій рамці, завдяки чому стає зрозуміло, що його не можна редагувати. Майте на увазі, що до нього додається стиль, тому, якщо ви хочете ідеальний попередній перегляд, це може бути не для вас. І я також загортаю все всередину Disabled
компонента, що робить все всередині неможливим для редагування, клацанням і перетягуванням. Це наша нова render()
функція в нашому компоненті:
Я також використовую компонент Fragment
( wp.element
пакет), який такий самий, як React.Fragment
. Якщо ви не знайомі з ним, ми загортаємо вивід у нього, коли не хочемо додавати зайві непотрібні обгортки HTML. У React все повинно мати кореневий вузол. Коли режим редагування активний (рядок #13
), ми виводимо два RichText
компоненти відразу один за одним, тому нам потрібен кореневий вузол навколо них.
Коли режим попереднього перегляду активний (рядок #29
), ми виводимо значення двох RichText
компонентів. Як і в save
, ми використовуємо RichText.Content
для повернення їхніх значень замість маленького редактора.
Компонент Placeholder
постачається у гнучкому стилі та за замовчуванням із гнучким напрямним рядком. Надання true
в опорі isColumnLayout
змінює його на стовпець зі змінним напрямком (так що все складається). Але, як згадувалося раніше, можливо, ви захочете пропустити цей компонент і краще створити попередній перегляд так, як це було б у інтерфейсі.
Крім того, у нас є перемикач попереднього перегляду/редагування блокового режиму. Очевидно, що ви можете налаштувати вміст «режиму редагування», щоб відобразити, наприклад, контрольні введення чи щось інше.
Ви можете створити скільки завгодно компонентів, ви не обмежені лише одним для edit
функції! Просто створіть більше компонентів і додайте їх у return
заяву. Насправді це і є ідея React – створення інкапсульованих фрагментів коду, кожен з яких, можливо, обробляє власний стан і об’єднує їх для створення складних інтерфейсів користувача.