Синтетические события в Preact

Preact использует модель синтетических событий, аналогичную той, что применяется в React. Это означает, что события, привязанные к компонентам, обрабатываются единым механизмом, который нормализует поведение событий в разных браузерах и упрощает управление ими.

Основы синтетических событий

События в Preact инкапсулируются в объекты типа SyntheticEvent. Эти объекты:

  • Обеспечивают единый интерфейс для различных типов событий (click, input, keydown и др.).
  • Нормализуют различия между браузерами.
  • Содержат методы preventDefault() и stopPropagation() для управления поведением событий.

Синтетические события создаются автоматически при использовании JSX и привязке обработчиков через атрибуты вида onClick, onInput, onChange.

import { h } from 'preact';

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

  return <button onCl ick={handleClick}>Нажми меня</button>;
}

В примере выше handleClick получает объект SyntheticEvent, который предоставляет доступ к свойствам оригинального события (event.target, event.type и т. д.), а также позволяет предотвращать стандартное поведение и останавливать всплытие.

Особенности работы

  1. Всплытие и делегирование Все синтетические события в Preact делегируются на корневой элемент приложения. Это уменьшает количество отдельных обработчиков в DOM и повышает производительность.

  2. Реальный DOM Объект SyntheticEvent содержит ссылку на оригинальное DOM-событие через свойство nativeEvent. Это позволяет при необходимости использовать стандартные методы работы с DOM.

  3. Поведение после асинхронных операций В Preact синтетические события повторно используют объекты для экономии памяти. После завершения обработчика свойства события могут быть очищены. Чтобы сохранить данные для асинхронной обработки, требуется копировать нужные значения:

function InputLogger() {
  const handleChange = (event) => {
    const value = event.target.value; // сохраняем значение
    setTimeout(() => {
      console.log('Асинхронное значение:', value);
    }, 1000);
  };

  return <input onIn put={handleChange} />;
}
  1. Типы событий Preact поддерживает основные типы событий: мыши, клавиатуры, форм, фокуса, сенсорные события. Привязка происходит через camelCase:
<input
  onFo cus={(e) => console.log('Фокус', e)}
  onB lur={(e) => console.log('Сброс фокуса', e)}
/>

Различия с нативными событиями

  • Единая обработка: Preact не создаёт отдельные обработчики для каждого элемента, а использует делегирование.
  • Экономия ресурсов: объекты SyntheticEvent переиспользуются, снижая нагрузку на сборщик мусора.
  • Нормализация браузеров: одинаковые свойства и методы доступны в разных браузерах без необходимости дополнительных проверок.

Работа с формами

Синтетические события упрощают управление формами:

function FormExample() {
  const handleSubmit = (event) => {
    event.preventDefault();
    console.log('Форма отправлена', event.target.elements);
  };

  return (
    <form onSub mit={handleSubmit}>
      <input name="username" />
      <button type="submit">Отправить</button>
    </form>
  );
}

Все элементы формы можно безопасно использовать через event.target, при этом всплытие контролируется стандартными методами SyntheticEvent.

Перехват событий на уровне компонента

Preact позволяет перехватывать события на родительских компонентах, используя стандартное всплытие:

function Parent() {
  const handleClick = (e) => {
    console.log('Событие на родителе');
  };

  return (
    <div onCl ick={handleClick}>
      <Child />
    </div>
  );
}

function Child() {
  return <button>Кнопка</button>;
}

Даже если клик произошёл на кнопке, обработчик родителя сработает благодаря делегированию синтетического события.

Асинхронные обновления состояния

При работе с хуками useState важно учитывать, что синтетические события могут быть уже очищены в асинхронных функциях. Необходимо сохранять значения из события до вызова асинхронного кода:

import { h } from 'preact';
import { useState } from 'preact/hooks';

function AsyncInput() {
  const [text, setText] = useState('');

  const handleChange = (event) => {
    const value = event.target.value;
    setTimeout(() => setText(value), 500);
  };

  return <input value={text} onIn put={handleChange} />;
}

Это предотвращает потерю данных и обеспечивает корректное обновление состояния.

Вывод

Синтетические события в Preact предоставляют мощный и оптимизированный инструмент для работы с пользовательским вводом. Их делегирование, нормализация и повторное использование объектов делают управление событиями более производительным, а единый интерфейс позволяет писать кроссбраузерный код без лишних проверок. Грамотное использование SyntheticEvent обеспечивает надежное управление формами, асинхронными операциями и компонентной иерархией.