State Management
Приложение использует два типа state management:
| Тип | Инструмент | Назначение |
|---|---|---|
| Server State | TanStack Query | Данные с сервера (курсы, уроки, прогресс) |
| Client State | Zustand | UI состояние (тема, язык, игры) |
Zustand Stores
Все stores находятся в src/stores/:
Persist Stores (сохраняются в AsyncStorage)
// src/stores/settings.ts
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';
interface SettingsState {
theme: 'light' | 'dark' | 'system';
language: 'en' | 'ru' | 'uk';
notificationsEnabled: boolean;
setTheme: (theme: SettingsState['theme']) => void;
setLanguage: (language: SettingsState['language']) => void;
}
export const useSettingsStore = create<SettingsState>()(
persist(
(set) => ({
theme: 'system',
language: 'en',
notificationsEnabled: true,
setTheme: (theme) => set({ theme }),
setLanguage: (language) => set({ language }),
}),
{
name: 'settings-storage',
storage: createJSONStorage(() => AsyncStorage),
}
)
);
Ephemeral Stores (только в памяти)
// src/stores/memory-cards-store.ts
import { create } from 'zustand';
interface MemoryCardsState {
cards: Card[];
flippedIndices: number[];
matchedPairs: number[];
moves: number;
flipCard: (index: number) => void;
reset: () => void;
}
export const useMemoryCardsStore = create<MemoryCardsState>((set) => ({
cards: [],
flippedIndices: [],
matchedPairs: [],
moves: 0,
flipCard: (index) => set((state) => ({
flippedIndices: [...state.flippedIndices, index],
moves: state.moves + 1,
})),
reset: () => set({
cards: [],
flippedIndices: [],
matchedPairs: [],
moves: 0,
}),
}));
Список stores
| Store | Persist | Назначение |
|---|---|---|
settings.ts | ✅ | Тема, язык, уведомления |
chat-store.ts | ❌ | Сообщения AI чата |
lesson-viewer-store.ts | ❌ | Скролл, активная вкладка |
lesson-progress-store.ts | ❌ | Временный прогресс урока |
mindmap-store.ts | ❌ | Pan/zoom состояние |
memory-cards-store.ts | ❌ | Состояние игры Memory |
pattern-sequence-store.ts | ❌ | Состояние игры Pattern |
learning-style-store.ts | ❌ | VARK quiz состояние |
course-creation-store.ts | ❌ | Wizard создания курса |
Паттерны использования
Селекторы (для оптимизации ререндеров)
// ❌ Плохо — компонент ререндерится при любом изменении store
const store = useSettingsStore();
// ✅ Хорошо — только при изменении theme
const theme = useSettingsStore((state) => state.theme);
Actions внутри store
// Все actions определяются в store
export const useChatStore = create<ChatState>((set, get) => ({
messages: [],
addMessage: (message) => set((state) => ({
messages: [...state.messages, message],
})),
clearMessages: () => set({ messages: [] }),
// Доступ к текущему состоянию через get()
getLastMessage: () => {
const { messages } = get();
return messages[messages.length - 1];
},
}));
Подписка на изменения
// Подписка вне React компонента
const unsubscribe = useSettingsStore.subscribe(
(state) => state.theme,
(theme) => {
console.log('Theme changed:', theme);
}
);
TanStack Query для Server State
Server state управляется через TanStack Query. См. Data Fetching.