Bliss.js предоставляет разработчику мощный механизм реактивности через hooks, позволяющий управлять состоянием, эффектами и жизненным циклом компонентов. Хотя библиотека включает ряд стандартных hooks, создание собственных расширяет возможности реактивной архитектуры и упрощает повторное использование логики.
Кастомный hook — это функция, имя которой начинается с
use и которая может вызывать другие hooks внутри себя. Они
не являются компонентами, но позволяют инкапсулировать поведение и
состояние.
Пример базового пользовательского hook:
import { useState, useEffect } from 'bliss';
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
return { count, increment, decrement };
}
В этом примере useCounter инкапсулирует управление
числовым состоянием и предоставляет интерфейс для увеличения и
уменьшения значения. Любой компонент может использовать его так:
function CounterComponent() {
const { count, increment, decrement } = useCounter(10);
return (
<div>
<p>Счетчик: {count}</p>
<button oncl ick={increment}>+</button>
<button oncl ick={decrement}>-</button>
</div>
);
}
Hooks в Bliss.js поддерживают эффекты, которые
позволяют реагировать на изменения состояния или пропсов. Эффекты
создаются с помощью useEffect внутри кастомного hook:
import { useState, useEffect } from 'bliss';
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;
}
Здесь useWindowWidth отслеживает ширину окна и обновляет
состояние при изменении размера. useEffect гарантирует
корректное добавление и удаление обработчика.
Hooks можно делать параметризованными, чтобы они адаптировались к различным сценариям:
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
const stored = localStorage.getItem(key);
return stored !== null ? JSON.parse(stored) : initialValue;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}
Такой hook можно использовать для любого ключа и начального значения, создавая реактивное хранилище в локальном хранилище браузера.
Bliss.js позволяет комбинировать несколько hooks внутри одного кастомного. Это полезно для создания сложной логики без дублирования кода:
function useResponsiveCounter(initialValue = 0) {
const width = useWindowWidth();
const { count, increment, decrement } = useCounter(initialValue);
useEffect(() => {
if (width < 500) {
console.log('Маленький экран, уменьшение счетчика на 1');
decrement();
}
}, [width]);
return { count, increment, decrement, width };
}
Компонент получает сразу состояние счетчика и ширину экрана, а также автоматическое поведение при изменении размера окна.
Создание собственных hooks позволяет стандартизировать подходы к управлению состоянием и эффектами. В больших приложениях можно собрать библиотеку hooks, которая упрощает разработку новых компонентов, уменьшает дублирование кода и повышает читаемость.
function useAuth() {
const [user, setUser] = useState(null);
const login = async (credentials) => {
const response = await fetch('/login', { method: 'POST', body: JSON.stringify(credentials) });
const data = await response.json();
setUser(data.user);
};
const logout = () => setUser(null);
return { user, login, logout };
}
Такой hook инкапсулирует авторизацию, позволяя любому компоненту подключаться к состоянию пользователя без повторного написания логики запросов и обработки ответа.
Кастомные hooks тесно интегрируются с компонентами Bliss.js, поддерживая реактивный рендер при изменении состояния. Это делает архитектуру более модульной, а код — предсказуемым.
Hooks можно использовать как для UI-логики, так и для работы с внешними API, хранилищем данных, подписками на события и анимациями, обеспечивая единый подход к управлению состоянием и эффектами.