Контролируемые компоненты — это компоненты, состояние которых полностью определяется внешними свойствами. В SkateJS концепция контролируемых компонентов тесно связана с свойствами (props) и реактивностью, позволяя управлять состоянием компонента извне и избегать внутренних конфликтов данных.
В SkateJS свойства компонента объявляются через функцию
props. Каждое свойство может иметь:
String, Number, Boolean,
Object, Array).default.set), которая
вызывается при изменении значения.Пример объявления свойств:
import { define, props, Component } from 'skatejs';
class ControlledInput extends Component {
static get props() {
return {
value: props.string({ default: '' }),
disabled: props.boolean({ default: false })
};
}
renderCallback() {
return (
<input
value={this.value}
disabled={this.disabled}
onIn put={e => this._onInput(e)}
/>
);
}
_onInput(event) {
this.value = event.target.value;
}
}
define('controlled-input', ControlledInput);
Здесь свойство value делает компонент
контролируемым. Любые изменения внешнего свойства
value автоматически обновляют отображаемое значение в
<input>.
Для контролируемых компонентов важно различать внутренние
изменения состояния и внешние изменения
свойства. SkateJS предоставляет механизм наблюдателей
(observers) через опцию set в объявлении
свойства:
static get props() {
return {
value: props.string({
default: '',
set(newValue, oldValue) {
if (newValue !== oldValue) {
console.log(`value изменилось с ${oldValue} на ${newValue}`);
}
return newValue;
}
})
};
}
set позволяет выполнять дополнительные действия при
обновлении свойства, но при этом возвращаемое значение становится
фактическим значением свойства.
Контролируемые компоненты часто используют кастомные события, чтобы уведомлять внешние компоненты о внутреннем изменении:
_onInput(event) {
const newValue = event.target.value;
this.dispatchEvent(new CustomEvent('value-change', {
detail: newValue,
bubbles: true,
composed: true
}));
}
События позволяют родительскому компоненту реагировать на изменения и
обновлять свойство value, сохраняя полный контроль над
состоянием компонента.
Неконтролируемый компонент хранит внутреннее состояние и может изменять его без внешнего вмешательства. Контролируемый компонент:
Пример комбинированного подхода:
class MixedInput extends Component {
static get props() {
return {
value: props.string(),
defaultValue: props.string({ default: '' })
};
}
constructor() {
super();
this._internalValue = this.defaultValue;
}
renderCallback() {
const displayValue = this.value !== undefined ? this.value : this._internalValue;
return (
<input
value={displayValue}
onIn put={e => this._onInput(e)}
/>
);
}
_onInput(event) {
const newValue = event.target.value;
if (this.value === undefined) {
this._internalValue = newValue; // неконтролируемое поведение
} else {
this.dispatchEvent(new CustomEvent('value-change', {
detail: newValue,
bubbles: true,
composed: true
}));
}
}
}
define('mixed-input', MixedInput);
В этом примере компонент работает как контролируемый, если
есть значение value, и как неконтролируемый — если его
нет.
Контролируемые компоненты активно используют жизненный цикл SkateJS для отслеживания изменений:
connectedCallback — настройка слушателей, начальная
инициализация.updatedCallback — реакция на изменение свойств и
синхронизация с DOM.disconnectedCallback — очистка ресурсов и событий.Пример использования updatedCallback для
синхронизации:
updatedCallback(oldProps) {
if (oldProps.value !== this.value) {
console.log('Внешнее свойство value изменилось');
}
}
Контролируемые компоненты в SkateJS обеспечивают чёткую архитектуру данных, предсказуемость и удобство интеграции с другими библиотеками и фреймворками. Они идеально подходят для построения сложных интерфейсов с динамическим состоянием и строгим контролем поведения.