Функциональные компоненты

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

Создание функционального компонента

Синтаксис функционального компонента прост:

import { h } from 'preact';

function Button({ label, onClick }) {
    return (
        <button onCl ick={onClick}>
            {label}
        </button>
    );
}

export default Button;

Основные моменты:

  • Функция принимает объект props, который содержит все свойства, переданные компоненту.
  • Возвращаемое значение — JSX-элемент, описывающий структуру интерфейса.
  • Отсутствует собственное состояние, если не использовать хуки.

Использование props

Props позволяют компоненту быть динамичным и повторно используемым. Значения передаются при рендеринге:

<Button label="Сохранить" onCl ick={() => console.log('Сохранено')} />
<Button label="Отмена" onCl ick={() => console.log('Отменено')} />

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

function Alert({ message, type }) {
    return (
        <div className={`alert alert-${type}`}>
            {message}
        </div>
    );
}

Хуки состояния

Функциональные компоненты могут управлять состоянием с помощью хуков, таких как useState. Это позволяет компонентам быть интерактивными без необходимости классовых компонентов.

Пример использования useState:

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

function Counter() {
    const [count, setCount] = useState(0);

    return (
        <div>
            <p>Счет: {count}</p>
            <button onCl ick={() => setCount(count + 1)}>Увеличить</button>
            <button onCl ick={() => setCount(count - 1)}>Уменьшить</button>
        </div>
    );
}

Ключевые аспекты работы с хуками:

  • useState(initialValue) возвращает массив из текущего значения состояния и функции для его обновления.
  • При изменении состояния компонент автоматически перерисовывается.
  • Хуки должны вызываться на верхнем уровне функции, нельзя вызывать их внутри условий или циклов.

Эффекты и жизненный цикл

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

import { useEffect } from 'preact/hooks';

function Timer() {
    const [time, setTime] = useState(0);

    useEffect(() => {
        const interval = setInterval(() => {
            setTime(prev => prev + 1);
        }, 1000);

        return () => clearInterval(interval);
    }, []);

    return <p>Прошло секунд: {time}</p>;
}

Особенности:

  • Первый аргумент — функция, выполняющаяся после рендера.
  • Второй аргумент — массив зависимостей. Пустой массив означает выполнение только один раз при монтировании.
  • Возвращаемая функция используется для очистки ресурсов при размонтировании компонента.

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

События в Preact обрабатываются через атрибуты JSX, аналогично стандартным HTML-событиям. Отличия от React минимальны, за исключением некоторых нюансов производительности.

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

    return (
        <input
            type="text"
            value={text}
            onIn put={e => setText(e.target.value)}
        />
    );
}

Особенности:

  • События используют camelCase (onClick, onInput, onChange).
  • Для текстовых полей рекомендуется onInput вместо onChange для мгновенного реагирования на ввод.
  • Значения состояния синхронизируются с элементом через controlled component.

Вложенные и композиционные компоненты

Функциональные компоненты легко комбинировать. Один компонент может использовать другой для построения более сложных интерфейсов:

function Card({ title, content }) {
    return (
        <div className="card">
            <h2>{title}</h2>
            <p>{content}</p>
        </div>
    );
}

function App() {
    return (
        <div>
            <Card title="Заголовок 1" content="Текст карточки 1" />
            <Card title="Заголовок 2" content="Текст карточки 2" />
        </div>
    );
}

Композиция компонентов позволяет разделять интерфейс на логические части, повышая повторное использование кода.

Оптимизация функциональных компонентов

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

import { memo } from 'preact/compat';

const ExpensiveComponent = memo(function({ data }) {
    console.log('Рендер компонента');
    return <div>{data}</div>;
});

Особенности:

  • memo сравнивает текущие и предыдущие props.
  • Если props не изменились, компонент не перерисовывается.
  • Полезно для компонентов с тяжелой отрисовкой или сложной логикой.

Особенности Preact

  • Функциональные компоненты в Preact меньше по размеру, чем в React, что снижает вес приложения.
  • Поскольку Preact использует h() под капотом, JSX-компиляция преобразует синтаксис в компактные вызовы функций.
  • Hooks работают идентично React, что облегчает перенос проектов и библиотек.

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