Обработчики событий

В Preact обработка событий реализуется аналогично React, но с некоторыми особенностями, связанными с размером библиотеки и оптимизацией производительности. События в Preact привязываются через JSX-атрибуты, где имя события указывается в camelCase, а значение — функция-обработчик.

Основы синтаксиса

import { h } from 'preact';

function Button() {
    function handleClick(event) {
        console.log('Клик по кнопке', event);
    }

    return <button onCl ick={handleClick}>Нажми меня</button>;
}
  • onClick — стандартный обработчик клика.
  • event — объект события, аналогичный нативному MouseEvent, KeyboardEvent и другим.
  • В Preact все события делегируются на уровне корневого элемента, что уменьшает количество слушателей в DOM и повышает производительность.

Отличия от стандартного DOM

  • События не добавляются напрямую к DOM-элементам, а регистрируются через внутренний механизм делегирования.
  • event в обработчиках является объектом Preact Synthetic Event, который оборачивает нативное событие и обеспечивает совместимость с разными браузерами.
  • Поддерживаются все стандартные события: onClick, onChange, onInput, onSubmit, onKeyDown и др.

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

Для передачи аргументов в обработчик используется функция-обёртка:

function ListItem({ item, onRemove }) {
    return (
        <li>
            {item.name}
            <button onCl ick={() => onRemove(item.id)}>Удалить</button>
        </li>
    );
}
  • Нельзя напрямую писать onCl ick={onRemove(item.id)}, так как это вызовет функцию сразу при рендере.
  • Функция-обёртка позволяет отложить вызов до момента события.

Управление формами

События форм, такие как onInput и onChange, имеют особенности:

function FormExample() {
    const [value, setValue] = useState('');

    function handleInput(event) {
        setValue(event.target.value);
    }

    return <input type="text" value={value} onIn put={handleInput} />;
}
  • onInput срабатывает при каждом изменении текста, onChange — при потере фокуса (поведение может отличаться от браузера к браузеру).
  • Preact поддерживает контролируемые компоненты аналогично React.

События клавиатуры

function KeyPressExample() {
    function handleKeyDown(event) {
        if (event.key === 'Enter') {
            console.log('Нажата клавиша Enter');
        }
    }

    return <input type="text" onKeyD own={handleKeyDown} />;
}
  • Все клавиатурные события (onKeyDown, onKeyUp, onKeyPress) используют объект события, который содержит свойства key, code, ctrlKey, shiftKey и другие.
  • Для предотвращения стандартного поведения используется event.preventDefault(), для остановки всплытия — event.stopPropagation().

События мыши и указателя

function MouseExample() {
    function handleMouseOver(event) {
        console.log('Наведение мыши на элемент');
    }

    return <div onMouseO ver={handleMouseOver}>Наведи курсор</div>;
}
  • Поддерживаются события мыши: onClick, onDoubleClick, onMouseDown, onMouseUp, onMouseMove, onMouseEnter, onMouseLeave.
  • События указателя (PointerEvent) позволяют работать с сенсорными экранами и стилусами.

Переиспользование обработчиков

Обработчики можно хранить отдельно для повторного использования:

function logEvent(event) {
    console.log(event.type, event.target);
}

function Component() {
    return (
        <div onCl ick={logEvent} onMouseO ver={logEvent}>
            Действия с мышью
        </div>
    );
}
  • Такой подход уменьшает количество создаваемых функций и улучшает производительность.
  • Особенно полезно при большом количестве элементов в списках.

Особенности производительности

  • Preact использует делегирование событий: все события обрабатываются на уровне корня приложения, что снижает нагрузку на DOM.
  • События автоматически очищаются при удалении компонентов, утечки памяти практически исключены.
  • Не требуется ручная отмена подписки на события при размонтировании компонентов.

Интерактивные элементы и события

Для компонентов, реализующих собственную логику взаимодействия, можно комбинировать обработчики событий с useState и useEffect:

function ToggleButton() {
    const [active, setActive] = useState(false);

    function handleClick() {
        setActive(!active);
    }

    return <button onCl ick={handleClick}>{active ? 'Вкл' : 'Выкл'}</button>;
}
  • Комбинация состояния и событий позволяет строить динамический интерфейс.
  • При необходимости можно использовать useEffect для побочных эффектов после срабатывания событий.

Делегирование и кастомные события

  • Preact поддерживает кастомные события, которые могут быть созданы через CustomEvent и слушаться с помощью onEventName.
  • Кастомные события удобно применять для связи между компонентами без глобального состояния или контекста.
function Child() {
    function sendEvent() {
        const event = new CustomEvent('myEvent', { detail: { value: 42 } });
        window.dispatchEvent(event);
    }

    return <button onCl ick={sendEvent}>Отправить событие</button>;
}

window.addEventListener('myEvent', (e) => {
    console.log('Получено событие', e.detail.value);
});
  • Использование кастомных событий позволяет реализовать сложные паттерны коммуникации между компонентами без прокидывания пропсов через несколько уровней.

Обработчики событий в Preact обеспечивают гибкий и производительный способ реагирования на действия пользователя, сочетая синтаксис JSX с делегированием и объектами Synthetic Event. Такой подход делает интерфейсы интерактивными, поддерживаемыми и легко расширяемыми.