Пользовательские события

Inferno предоставляет гибкий механизм работы с пользовательскими событиями, который позволяет создавать высокопроизводительные и легко управляемые интерфейсы. В основе работы с событиями лежит концепция привязки функций-обработчиков к элементам виртуального DOM и последующая эффективная синхронизация с реальным DOM.

Основы событийной модели

В Inferno события обрабатываются через свойства компонентов, которые начинаются с on и за которыми следует название события с большой буквы. Например:

const button = <button onCl ick={handleClick}>Нажать</button>;
  • onClick — привязка события клика мыши.
  • handleClick — функция-обработчик, вызываемая при срабатывании события.

Важной особенностью является динамическая привязка событий: если свойство обработчика изменяется между рендерами, Inferno корректно обновляет обработчики, не создавая лишних подписок на DOM-события.

Передача аргументов в обработчики

В отличие от нативного DOM, в Inferno можно легко передавать дополнительные аргументы через замыкания:

const handleClick = (id, event) => {
    console.log('Кнопка с id:', id);
};

const button = <button onCl ick={(e) => handleClick(42, e)}>Нажать</button>;

Особенность: event всегда передаётся последним аргументом, что сохраняет совместимость с нативными событиями.

События компонентов

В функциональных и классовых компонентах пользовательские события используются для коммуникации между компонентами. Обычно это делается через коллбэки, передаваемые в props:

function Child({ onAction }) {
    return <button onCl ick={() => onAction('data')}>Действие</button>;
}

function Parent() {
    const handleAction = (value) => console.log(value);
    return <Child onAct ion={handleAction} />;
}

Такой подход позволяет реализовывать однонаправленный поток данных, где родитель управляет состоянием, а дочерний компонент лишь уведомляет о событии.

Поддержка всех стандартных событий

Inferno поддерживает полный набор стандартных событий DOM:

  • События мыши: onClick, onDoubleClick, onMouseEnter, onMouseLeave.
  • События клавиатуры: onKeyDown, onKeyUp, onKeyPress.
  • События формы: onChange, onInput, onSubmit.
  • События фокуса: onFocus, onBlur.

Каждое событие в Inferno автоматически делегируется через внутренний обработчик на корневом уровне, что уменьшает количество подписок на реальные DOM-элементы и повышает производительность приложений с большим числом интерактивных элементов.

Работа с кастомными событиями

Для компонентов можно создавать собственные события через props:

function CustomComponent({ onCustom }) {
    const trigger = () => {
        if (onCustom) onCustom('значение');
    };
    return <div onCl ick={trigger}>Триггер</div>;
}

При использовании такого компонента:

<CustomComponent onCus tom={(value) => console.log('Событие:', value)} />

Такой паттерн позволяет реализовывать событийную модель компонентов, схожую с EventEmitter, но встроенную в структуру Inferno.

Особенности оптимизации

Inferno оптимизирует обработку событий через внутреннее делегирование:

  1. Все события одного типа делегируются на корневой контейнер.
  2. Обработчики вызываются только для тех элементов, которые реально присутствуют в виртуальном DOM.
  3. При обновлении компонентов добавление и удаление обработчиков происходит автоматически, что предотвращает утечки памяти.
function List({ items, onItemClick }) {
    return (
        <ul>
            {items.map(item => (
                <li key={item.id} onCl ick={() => onItemClick(item.id)}>{item.name}</li>
            ))}
        </ul>
    );
}

Даже при динамическом изменении списка Inferno корректно управляет событиями без необходимости ручной очистки подписок.

События и асинхронные действия

Обработчики в Inferno могут быть асинхронными. Важно учитывать, что виртуальный DOM может быть обновлён до завершения асинхронной операции:

async function handleAsync(event) {
    const data = await fetchData();
    console.log(data);
}
<button onCl ick={handleAsync}>Загрузить</button>

Для предотвращения проблем с состоянием часто используют локальные состояния компонента или эффекты с проверкой актуальности данных, чтобы обработчик не изменял уже удалённый элемент.

Отличия от React

  • Inferno использует более лёгкую и быструю систему событий, что делает обработку кликов и вводов заметно быстрее.
  • Внутреннее делегирование снижает нагрузку на браузер при большом количестве элементов.
  • API по обработке событий почти идентичен React, что облегчает миграцию к Inferno.

Рекомендации по проектированию событий

  • Предпочтительно использовать props для передачи коллбэков, а не глобальные события.
  • Минимизировать создание новых функций внутри JSX при больших списках — лучше выносить обработчики наружу и использовать замыкания.
  • Использовать ключи (key) при динамических списках, чтобы Inferno корректно обновлял события при изменении структуры DOM.

Эти практики позволяют поддерживать производительность и предсказуемость поведения компонентов при работе с пользовательскими событиями.