В библиотеке Bliss.js hooks представляют собой механизм для управления состоянием, жизненным циклом и поведением компонентов в реактивном стиле. Они позволяют отделить логику работы с DOM и состоянием от структуры разметки, обеспечивая чистый и удобный код. Hooks в Bliss.js можно рассматривать как функции, которые подключаются к компонентам и реагируют на изменения данных, событий или жизненного цикла.
useState — базовый hook для управления локальным состоянием. Он позволяет хранить значение и обновлять его, вызывая повторный рендер компонента при изменении.
Пример использования:
import { useState } from 'blissjs';
function Counter() {
const [count, setCount] = useState(0);
return `
<div>
<p>Счетчик: ${count}</p>
<button oncl ick="${() => setCount(count + 1)}">Увеличить</button>
</div>
`;
}
Ключевые моменты:
useState(initialValue) возвращает массив из текущего
значения и функции для его обновления.setCount автоматически
обновляет компонент.useEffect предназначен для работы с побочными эффектами: запросами к серверу, подписками на события, таймерами и другими действиями, не связанными напрямую с рендером. Он аналогичен методам жизненного цикла в классических компонентах.
Пример:
import { useState, useEffect } from 'blissjs';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => setSeconds(s => s + 1), 1000);
return () => clearInterval(interval);
}, []);
return `<p>Прошло секунд: ${seconds}</p>`;
}
Особенности:
useEffect — функция, выполняющая
побочный эффект.useRef позволяет хранить ссылки на элементы DOM или любые данные, которые не должны вызывать повторный рендер при изменении.
import { useRef, useEffect } from 'blissjs';
function InputFocus() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return `<input type="text" ref="${inputRef}"/>`;
}
Характерные свойства:
useRef(initialValue) возвращает объект с полем
current.current не вызывает обновления
компонента.Для компонентов с тяжелой логикой используются useMemo и useCallback.
useMemo кэширует результат функции:
import { useMemo, useState } from 'blissjs';
function Fibonacci({ n }) {
const fib = useMemo(() => {
function calcFib(x) {
if (x <= 1) return x;
return calcFib(x - 1) + calcFib(x - 2);
}
return calcFib(n);
}, [n]);
return `<p>Фибоначчи(${n}) = ${fib}</p>`;
}
useCallback кэширует функцию, предотвращая её пересоздание при каждом рендере:
import { useState, useCallback } from 'blissjs';
function ButtonCounter() {
const [count, setCount] = useState(0);
const increment = useCallback(() => setCount(c => c + 1), []);
return `<button oncl ick="${increment}">Нажато ${count} раз</button>`;
}
Ключевые принципы:
useMemo(fn, deps) выполняет функцию fn
только при изменении зависимостей deps.useCallback(fn, deps) возвращает мемоизированную
функцию, обновляющуюся только при изменении deps.Bliss.js позволяет создавать собственные hooks для повторного использования логики.
Пример:
import { useState, useEffect } from 'blissjs';
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return width;
}
function WidthDisplay() {
const width = useWindowWidth();
return `<p>Ширина окна: ${width}px</p>`;
}
Особенности пользовательских hooks:
use.Вызывать только на верхнем уровне компонента. Hooks нельзя вызывать внутри условных операторов, циклов или вложенных функций. Это сохраняет предсказуемость порядка вызова.
Использовать только внутри компонентов или других hooks. Нельзя вызывать вне функций компонентов или пользовательских hooks.
Чётко определять зависимости для эффектов и мемоизации. Неправильный список зависимостей может привести к багам и лишним рендерам.
Разделять логику состояния и представления. Hooks позволяют изолировать функциональность, что улучшает читаемость и тестируемость кода.
Bliss.js обеспечивает реактивное обновление DOM при изменении состояния. Основной принцип:
Hooks можно комбинировать, создавая сложные компоненты:
import { useState, useEffect, useRef } from 'blissjs';
function ChatBox() {
const [messages, setMessages] = useState([]);
const inputRef = useRef(null);
useEffect(() => {
const timer = setInterval(() => {
setMessages(prev => [...prev, `Сообщение ${prev.length + 1}`]);
}, 3000);
return () => clearInterval(timer);
}, []);
const sendMessage = () => {
setMessages(prev => [...prev, inputRef.current.value]);
inputRef.current.value = '';
};
return `
<div>
<ul>${messages.map(m => `<li>${m}</li>`).join('')}</ul>
<input ref="${inputRef}"/>
<button oncl ick="${sendMessage}">Отправить</button>
</div>
`;
}
Комбинирование позволяет:
Hooks в Bliss.js создают фундамент для реактивного программирования, обеспечивая гибкость и контроль над состоянием и побочными эффектами без усложнения структуры кода.