Preact, как лёгкий и высокопроизводительный фреймворк для разработки интерфейсов на JavaScript, наследует многие концепции из React, включая систему хуков. Хуки позволяют управлять состоянием компонентов, выполнять побочные эффекты и создавать переиспользуемую логику. Создание пользовательских хуков расширяет возможности компонентов и позволяет структурировать код более эффективно.
Пользовательский хук — это функция, имя которой начинается с префикса
use и которая внутри себя может использовать стандартные
хуки Preact (useState, useEffect,
useRef, useMemo, useCallback).
Основная цель пользовательских хуков — инкапсулировать логику, которую
можно применять в разных компонентах без дублирования кода.
Пример простого пользовательского хука для счётчика:
import { useState } from 'preact/hooks';
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(prev => prev + 1);
const decrement = () => setCount(prev => prev - 1);
const reset = () => setCount(initialValue);
return { count, increment, decrement, reset };
}
В этом примере useCounter управляет состоянием числа и
предоставляет методы для его изменения. Такой хук можно использовать в
любом компоненте:
function CounterComponent() {
const { count, increment, decrement, reset } = useCounter(5);
return (
<div>
<p>Счёт: {count}</p>
<button onCl ick={increment}>+</button>
<button onCl ick={decrement}>-</button>
<button onCl ick={reset}>Сброс</button>
</div>
);
}
Пользовательские хуки могут использовать несколько встроенных хуков одновременно, создавая сложную логику управления состоянием и побочными эффектами. Это особенно полезно для обработки форм, анимаций и сетевых запросов.
Пример пользовательского хука для работы с API:
import { useState, useEffect } from 'preact/hooks';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
setLoading(true);
fetch(url)
.then(response => {
if (!response.ok) throw new Error('Ошибка сети');
return response.json();
})
.then(json => setData(json))
.catch(err => setError(err))
.finally(() => setLoading(false));
}, [url]);
return { data, loading, error };
}
Использование этого хука в компоненте выглядит лаконично:
function UsersList() {
const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/users');
if (loading) return <p>Загрузка...</p>;
if (error) return <p>Ошибка: {error.message}</p>;
return (
<ul>
{data.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
);
}
Для оптимизации производительности часто используют
useMemo и useCallback внутри пользовательских
хуков. Это позволяет избегать лишних пересчётов значений и пересоздания
функций при ререндере.
Пример хука с мемоизацией:
import { useState, useMemo } from 'preact/hooks';
function useFilteredList(items, filter) {
const [search, setSearch] = useState('');
const filteredItems = useMemo(() => {
return items.filter(item => item.toLowerCase().includes(search.toLowerCase()));
}, [items, search, filter]);
return { filteredItems, search, setSearch };
}
Создание пользовательских хуков повышает читаемость и структуру проекта. Основные рекомендации при разработке хуков:
use и отражать
функциональность.useEffect.useEffect или useMemo.import { useState, useEffect } from 'preact/hooks';
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initialValue;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}
import { useState, useEffect } from 'preact/hooks';
function useWindowSize() {
const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });
useEffect(() => {
const handleResize = () => setSize({ width: window.innerWidth, height: window.innerHeight });
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return size;
}
Пользовательские хуки в Preact позволяют создавать чистый, повторно используемый и легко тестируемый код, уменьшая дублирование логики и повышая масштабируемость приложений. Такой подход способствует более структурированному управлению состоянием и побочными эффектами в компонентах любого уровня сложности.