State Management (Zustand)
Relevant source files
The following files were used as context for generating this wiki page:The eefashiondesign project utilizes Zustand as its primary state management library. Zustand is chosen for its simplicity, lightweight nature, and minimal boilerplate, providing a scalable and maintainable state architecture. The state is organized into multiple modular, feature-specific stores, some of which are persisted to the device's local storage for a seamless user experience.
The overall architecture promotes a clean separation of concerns, with UI components interacting with state through custom hooks, which in turn consume the underlying Zustand stores. This approach abstracts the state logic, making components cleaner and state management more centralized and testable.
Sources: README.md, TASK_4_DISCUSSION.md
Architecture Overview
The state management architecture is built around a collection of independent stores, each responsible for a specific domain or feature. The main store definitions are located in src/store/index.js. A separate, more detailed authStore is defined in its own file to handle user authentication state.
This diagram illustrates the high-level data flow from UI components to the state stores and persistence layer.
State Persistence
Several stores use Zustand's persist middleware to save their state to AsyncStorage. This ensures that critical application data, such as user settings, saved designs, and tutorial progress, is not lost between sessions. The middleware is configured with a unique name (storage key) and uses createJSONStorage to interface with AsyncStorage.
The following diagram shows the process of a state update being persisted.
The keys used for storing data are centralized in src/core/utils/constants.js. An older, deprecated constants file also exists at src/config/constants.js.
| Storage Key | Description | Source File |
|---|---|---|
@auth_token | Stores the user's authentication token. | src/core/utils/constants.js |
@refresh_token | Stores the user's refresh token. | src/core/utils/constants.js |
@user_data | Stores user profile information. | src/core/utils/constants.js |
@theme | The current application theme ('dark' or 'light'). | src/core/utils/constants.js |
@designs | Stores saved user designs and history. | src/core/utils/constants.js |
@projects | Stores collaborative project data. | src/core/utils/constants.js |
@measurements | Stores user measurement profiles. | src/core/utils/constants.js |
@templates | Stores user's favorite templates. | src/core/utils/constants.js |
@settings | General application settings. | src/core/utils/constants.js |
@onboarding_completed | Flag indicating if the user has completed onboarding. | src/core/utils/constants.js |
@last_sync | Timestamp of the last cloud sync. | src/core/utils/constants.js |
@tutorial_state | The state of the interactive tutorial. | src/store/index.js:241 |
Sources: src/core/utils/constants.js:230-252, src/config/constants.js:101-112, SECURITY_AND_CLEANUP_FIXES.md
Core Stores
The application state is divided into several stores, each with a distinct responsibility.
authStore
This store manages all authentication-related state, including user session, profile data, and loading/error states during auth operations. It is defined in src/core/state/stores/authStore.js and consumed by the useAuth hook.
State Properties:
| Property | Type | Description |
|---|---|---|
session | object | null | The current user session object from Supabase. |
user | object | null | The current user's profile data. |
isAuthenticated | boolean | True if the user is authenticated. |
loading | boolean | True during async authentication operations. |
error | object | null | Stores any error that occurs during authentication. |
Actions:
| Action | Description |
|---|---|
setSession | Sets the session and user state. |
signIn | Handles user sign-in with email and password. |
signUp | Handles new user registration. |
signOut | Logs the user out and clears the session. |
updateUserProfile | Updates the user's profile data. |
sendPasswordResetEmail | Initiates the password reset process. |
Sources: src/core/state/stores/authStore.js, TASK_4_SUMMARY.md
The useAuth hook provides a clean interface for components to interact with the authStore. The following diagram shows a typical sign-in sequence.
useAppStore
This is a general-purpose store for global application state. It is persisted to AsyncStorage under the key @settings.
State & Actions:
| Name | Type | Description |
|---|---|---|
theme | string | The current theme ('dark' or 'light'). |
user | object | null | The authenticated user object. |
isAuthenticated | boolean | A flag indicating if the user is logged in. |
settings | object | An object containing user-configurable settings like notifications, autoSave, etc. |
onboardingCompleted | boolean | A flag to track if the user has completed the initial onboarding flow. |
setTheme | function | Sets the theme to a specific value. |
toggleTheme | function | Toggles between 'dark' and 'light' themes. |
setUser | function | Sets the user object and isAuthenticated flag. |
logout | function | Clears user data and sets isAuthenticated to false. |
updateSettings | function | Merges new settings into the existing settings object. |
setOnboardingCompleted | function | Sets the onboardingCompleted flag. |
Sources: src/store/index.js:8-32
useDesignStore
This store is central to the design functionality, managing the current design state, undo/redo history, and a list of all saved designs. It is persisted under the key @designs.
State & Actions:
| Name | Type | Description |
|---|---|---|
currentDesign | object | null | The design object currently being edited. |
history | array | An array of design states for undo/redo functionality. |
historyIndex | number | A pointer to the current position in the history array. |
savedDesigns | array | A list of all designs saved by the user. |
versions | object | An object to store auto-saved versions of designs, keyed by design ID. |
setCurrentDesign | function | Sets the active design. |
saveToHistory | function | Pushes a new design state to the history stack, enabling undo. |
undo / redo | function | Navigates backward or forward in the history stack. |
canUndo / canRedo | function | Returns a boolean indicating if undo/redo is possible. |
addDesign / updateDesign / deleteDesign | function | CRUD operations for the savedDesigns list. |
saveVersion | function | Saves a version of a design for auto-save recovery. |
Sources: src/store/index.js:37-113
The saveToHistory action implements the undo/redo logic. It slices the history array to the current index before pushing a new state, effectively clearing any "future" states when a new change is made.
Sources: src/store/index.js:48-62
useTutorialStore
This store manages the state of the in-app tutorial. It is persisted under @tutorial_state and used by components like HomeScreen to control the tutorial flow.
Example Usage in HomeScreen.js:
// src/features/home/screens/HomeScreen.js
import { useTutorialStore } from '../../../store';
const HomeScreen = ({ navigation }) => {
// ...
const { startTutorial } = useTutorialStore();
// ...
const quickActions = [
// ...
{
icon: <MaterialCommunityIcons name="school" size={24} color="#fff" />,
label: 'Tutorial',
color: '#A8E6CF',
action: () => startTutorial(),
},
];
// ...
};
Sources: src/features/home/screens/HomeScreen.js:23, 370-375, src/store/index.js:237-269
Other Stores
The application defines several other modular stores for specific features:
| Store Name | Responsibility | Persisted |
|---|---|---|
useMeasurementsStore | Manages user measurement profiles. | Yes (@measurements) |
useTemplatesStore | Manages favorite and recently used templates. | No |
useCollaborationStore | Manages collaborative projects and members. | No |
useNotificationStore | Manages in-app notifications and their read status. | No |
Sources: src/store/index.js:118-235