В Preact, как и в React, оптимизация
производительности компонентов часто достигается с помощью
хуков useMemo и useCallback. Они позволяют
контролировать повторные вычисления значений и пересоздание функций, что
критично при работе с большими компонентными деревьями и частыми
рендерами.
useMemo используется для кэширования результата
вычислений, чтобы избежать их повторного выполнения при каждом
рендере. Синтаксис выглядит следующим образом:
import { useMemo } from 'preact/hooks';
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Пример использования:
const numbers = [1, 2, 3, 4, 5];
const sum = useMemo(() => {
console.log('Вычисляем сумму...');
return numbers.reduce((acc, num) => acc + num, 0);
}, [numbers]);
В этом примере сумма чисел будет вычисляться только при
изменении массива numbers, что экономит ресурсы
при частых рендерах.
Особенности и советы по useMemo:
memo.useCallback служит для мемоизации
функций, чтобы они не создавались заново при каждом
рендере:
import { useCallback } from 'preact/hooks';
const memoizedHandler = useCallback(() => {
console.log('Обработчик вызван');
}, [dependency]);
memo, чтобы избежать ненужного рендера.Пример:
const Button = ({ onClick }) => (
<button onCl ick={onClick}>Нажми</button>
);
const App = () => {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(prev => prev + 1);
}, []);
return (
<>
<Button onCl ick={increment} />
<p>Счёт: {count}</p>
</>
);
};
Без useCallback функция increment
создавалась бы заново при каждом рендере, что могло бы вызывать
лишние рендеры дочернего компонента
Button, если он обёрнут в memo.
| Хук | Возвращаемое значение | Использование |
|---|---|---|
| useMemo | Вычисленное значение | Кэширование результатов вычислений, массивов, объектов |
| useCallback | Функция | Кэширование функций для передачи в дочерние компоненты |
Фактически, useCallback(fn, deps) эквивалентен
useMemo(() => fn, deps), но предназначен для повышения
читаемости кода.
const filteredData = useMemo(() => {
return data.filter(item => item.active).map(item => item.name);
}, [data]);
memo-компоненты:const Child = memo(({ onAction }) => {
console.log('Рендер Child');
return <button onCl ick={onAction}>Action</button>;
});
const Parent = () => {
const [value, setValue] = useState(0);
const handleAction = useCallback(() => setValue(v => v + 1), []);
return <Child onAct ion={handleAction} />;
};
const options = useMemo(() => [{ label: 'A', value: 1 }, { label: 'B', value: 2 }], []);
Использование useMemo и useCallback в
Preact позволяет значительно повысить производительность сложных
приложений, особенно при большом количестве компонентов и частых
обновлениях состояний. Правильное понимание разницы между этими хуками и
их правильное применение помогает избегать лишних рендеров и
обеспечивает стабильное поведение компонентов.