Preact, как минималистичная альтернатива React, предоставляет базовые
средства управления состоянием через хуки useState и
useReducer. Однако при увеличении сложности приложения
становится необходим более структурированный подход для глобального
состояния. Для таких случаев отлично подходят легковесные библиотеки,
одна из которых — Zustand. Она сочетает простоту, производительность и
компактность API.
Zustand реализует принцип хранения состояния в виде централизованного стора, к которому компоненты могут подписываться. Состояние в сторе является реактивным, что позволяет обновлять только те компоненты, которые используют изменённые данные. Основные элементы архитектуры:
Пример создания простого стора:
import create from 'zustand';
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}));
Здесь useStore — это кастомный хук, который позволяет
компонентам подписываться на состояние. Любое изменение через
increment или decrement автоматически приведёт
к рендеру компонентов, использующих count.
Zustand полностью совместим с Preact, так как использует стандартные
хуки React API. Для Preact следует убедиться, что проект использует
preact/compat, если требуется интеграция с библиотеками,
изначально рассчитанными на React.
Пример использования стора в Preact-компоненте:
import { h } from 'preact';
import { useStore } from './store';
function Counter() {
const count = useStore((state) => state.count);
const increment = useStore((state) => state.increment);
const decrement = useStore((state) => state.decrement);
return (
<div>
<h1>{count}</h1>
<button onCl ick={increment}>+</button>
<button onCl ick={decrement}>-</button>
</div>
);
}
Использование селекторов (state) => state.count
позволяет компоненту подписываться только на нужную часть состояния,
минимизируя лишние ререндеры.
Zustand выгодно отличается по нескольким параметрам:
const useUserStore = create((set) => ({
user: null,
setUser: (user) => set({ user }),
}));
const useThemeStore = create((set) => ({
theme: 'light',
toggleTheme: () => set((state) => ({ theme: state.theme === 'light' ? 'dark' : 'light' })),
}));
localStorage:import { devtools, persist } from 'zustand/middleware';
const useStore = create(
devtools(
persist(
(set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}),
{ name: 'counter-storage' }
)
)
);
Выбор между ними зависит от структуры приложения и требований к реактивности. Для большинства небольших и средних Preact-проектов Zustand обеспечивает баланс между простотой, производительностью и масштабируемостью.
Использование Zustand позволяет поддерживать Preact-приложение компактным, быстрым и легко расширяемым без перегрузки архитектуры сложными инструментами.