В Preact состояние компонентов играет ключевую роль в построении динамических интерфейсов. В отличие от традиционных подходов, где управление состоянием часто распределено по DOM-элементам, Preact предлагает функциональные методы работы с состоянием, позволяя строить масштабируемые и предсказуемые приложения.
Локальное состояние создаётся с помощью хука useState.
Оно применяется для хранения данных, которые непосредственно связаны с
конкретным компонентом и не влияют на другие части приложения.
import { h } from 'preact';
import { useState } from 'preact/hooks';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Счётчик: {count}</p>
<button onCl ick={() => setCount(count + 1)}>Увеличить</button>
</div>
);
}
Особенности локального состояния:
Для управления состоянием, которое должно быть доступно нескольким
компонентам, применяется контекст (createContext). Он
позволяет централизованно хранить данные и предоставлять их любому
компоненту в дереве.
import { h } from 'preact';
import { createContext } from 'preact';
import { useContext, useState } from 'preact/hooks';
const ThemeContext = createContext();
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
function ThemedButton() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<button
style={{ background: theme === 'light' ? '#fff' : '#333', color: theme === 'light' ? '#000' : '#fff' }}
onCl ick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
>
Переключить тему
</button>
);
}
Преимущества контекста:
useReducerДля компонентов с большим количеством логики изменения состояния
применяется useReducer. Он позволяет описывать все
возможные действия через редьюсер, что делает логику более предсказуемой
и тестируемой.
import { h } from 'preact';
import { useReducer } from 'preact/hooks';
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>Счётчик: {state.count}</p>
<button onCl ick={() => dispatch({ type: 'increment' })}>Увеличить</button>
<button onCl ick={() => dispatch({ type: 'decrement' })}>Уменьшить</button>
</div>
);
}
Преимущества useReducer:
Для больших приложений Preact может интегрироваться с внешними менеджерами состояния, такими как Redux или Zustand. Они предоставляют мощные механизмы для управления состоянием через глобальные хранилища, middleware и подписки.
Ключевые аспекты внешних менеджеров:
В реальных проектах часто применяется комбинация локального, контекстного и внешнего состояния. Локальное состояние отвечает за быстрые изменения UI, контекст — за разделяемые настройки и параметры, внешние хранилища — за глобальные данные и синхронизацию с сервером.
Принципы комбинированного подхода:
createContext только для данных, которые реально нужны в
нескольких компонентах.useReducer.Эти подходы создают основу для архитектурной устойчивости приложения и позволяют строить интерфейсы с предсказуемым поведением, минимизируя ошибки и повышая удобство поддержки кода.