В Fresh, фреймворке для создания современных веб-приложений на JavaScript и TypeScript с использованием Deno, концепция Hooks заимствована из подхода React, но адаптирована под серверный и клиентский рендеринг без необходимости виртуального DOM. Hooks позволяют управлять состоянием, жизненным циклом компонентов и побочными эффектами, сохраняя чистоту функций и предсказуемость поведения компонентов.
useState — базовый Hook для управления локальным
состоянием компонента.
import { useState } from "https://deno.land/x/fresh/hooks.ts";
function Counter() {
const [count, setCount] = useState(0);
return (
<button onCl ick={() => setCount(count + 1)}>
Счётчик: {count}
</button>
);
}
Ключевые моменты:
setCount заменяет
текущее значение новым. В отличие от классового состояния в React,
обновление полностью заменяет значение.useEffect управляет побочными эффектами, например,
сетевыми запросами или подписками. В Fresh Hook работает аналогично
React, но учитывает серверный рендеринг.
import { useEffect } from "https://deno.land/x/fresh/hooks.ts";
function DataFetcher() {
const [data, setData] = useState(null);
useEffect(() => {
fetch("/api/data")
.then(res => res.json())
.then(setData);
}, []);
return <div>{data ? JSON.stringify(data) : "Загрузка..."}</div>;
}
Особенности:
[] — один раз после
монтирования.useEffect(() => {
const interval = setInterval(() => console.log("Тик"), 1000);
return () => clearInterval(interval);
}, []);
useMemo и useCallback оптимизируют
производительность, предотвращая лишние вычисления или пересоздание
функций при каждом рендере.
import { useMemo, useCallback } from "https://deno.land/x/fresh/hooks.ts";
function ExpensiveComponent({ items }) {
const total = useMemo(() => {
return items.reduce((sum, item) => sum + item.value, 0);
}, [items]);
const handleClick = useCallback(() => {
console.log("Нажато");
}, []);
return <button onCl ick={handleClick}>Сумма: {total}</button>;
}
Ключевые моменты:
useMemo возвращает мемоизированное значение.useCallback возвращает мемоизированную функцию.useRef позволяет сохранять изменяемые объекты между
рендерами без вызова повторного рендера.
import { useRef } from "https://deno.land/x/fresh/hooks.ts";
function FocusInput() {
const inputRef = useRef(null);
const focus = () => inputRef.current?.focus();
return (
<>
<input ref={inputRef} />
<button onCl ick={focus}>Фокус</button>
</>
);
}
Применение:
const [count, setCount] = useState<number>(0);
Hooks можно комбинировать для реализации сложной логики:
function Timer() {
const [seconds, setSeconds] = useState(0);
const intervalRef = useRef<number | null>(null);
useEffect(() => {
intervalRef.current = setInterval(() => setSeconds(s => s + 1), 1000);
return () => intervalRef.current && clearInterval(intervalRef.current);
}, []);
const reset = useCallback(() => setSeconds(0), []);
return (
<div>
Время: {seconds} секунд
<button onCl ick={reset}>Сброс</button>
</div>
);
}
Такой подход демонстрирует модульность, чистоту функций и контроль жизненного цикла, которые являются основными преимуществами Hooks в Fresh.
useState для локального состояния
компонента, а глобальное состояние хранить через контексты или внешние
хранилища.useEffect разделять по задачам, чтобы не
создавать громоздкие функции.useMemo и useCallback только
там, где есть реальная нагрузка, чтобы избежать избыточного кода.useRef использовать для управления DOM и таймерами,
которые не должны вызывать ререндер.Hooks в Fresh формируют единый, предсказуемый и эффективный способ управления состоянием и поведением компонентов, позволяя создавать масштабируемые и отзывчивые веб-приложения.