State Management Architecture
**Referenced Files in This Document** - [[index.ts]](file/ui-web/src/store/index.ts) - [[useBiStore.ts]](file/ui-web/src/store/usebistore.ts) - [[useCommonStore.ts]](file/ui-web/src/store/usecommonstore.ts) - [[useSitePromotionStore.ts]](file/ui-web/src/store/usesitepromotionstore.ts) - [[bi.ts]](file/ui-web/src/api/bi.ts) - [[request.ts]](file/ui-web/src/utils/request.ts) - [[table.ts]](file/ui-web/src/hooks/table.ts)
Table of Contents
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
Introduction
This document describes the state management architecture used in the project’s frontend. It focuses on:
- Global state via Zustand stores for cross-component sharing
- Local component state using React hooks
- Store organization patterns, state slice management, and action dispatching
- Integration between global stores and local state, including hydration and persistence
- API state management for data fetching, caching strategies, and optimistic updates
- Practical examples for custom hooks, selectors, and complex state transitions
- Debugging tools, state serialization for SSR, and performance optimization for large state trees
Project Structure
The state management is organized around:
- Global stores under ui-web/src/store for shared application state
- API clients under ui-web/src/api for typed data fetching
- Utilities under ui-web/src/utils for request orchestration
- Local component state via React hooks under ui-web/src/hooks
Diagram sources
Section sources
Core Components
- useBiStore: Manages BI initialization, user info, menus, controls, notifications, and quick menu favorites. Provides initialization, refresh, toggle, and reset actions.
- useCommonStore: Centralizes dictionary data (shops, operators, categories, metrics metadata) and computes derived options and groups. Fetches data via parallel API calls.
- useSitePromotionStore: Local, persisted search filters for site-wide promotions with hydration and selective persistence.
- API module (bi.ts): Strongly typed endpoints for initialization, favorites, analytics preview, home data, templates, categories, and metrics.
- Request utilities (request.ts): Unified HTTP client with interceptors, token handling, timeouts, and environment-aware routing.
Section sources
Architecture Overview
The system follows a layered approach:
- UI components subscribe to Zustand stores and React hooks for local state
- Stores encapsulate state slices and actions; they call API functions from the API module
- The API module delegates HTTP requests to the request utilities, which handle tokens, timeouts, and environment routing
- Some stores persist subsets of state to localStorage for hydration across sessions
Diagram sources
Detailed Component Analysis
Global Store: useBiStore
- Purpose: Initialize and manage BI system-wide state (auth, user, operational info, menus, controls, notifications, quick menus).
- State slices:
- Data: auth, user, oper, menu, control, extend, notifiData, quickMenus
- Flags: initialized, loading, error
- Actions:
- initBiData: guarded initialization with loading/error flags, parses quick menu JSON, sets state
- refreshMenu: re-fetches menu list
- toggleQuickMenu: toggles a menu key in quickMenus and persists via API
- isQuickMenu: checks membership in quickMenus
- reset: clears all state to initial values
Diagram sources
Section sources
Global Store: useCommonStore
- Purpose: Provide dictionary data and derived options for UI components (stores, operators, categories, metrics metadata).
- State slices:
- Raw data: shopData, shopZtaiData, oper, com, bas_category, net_category, bi_dimension, bi_field, bi_amortiz_subject, collect, note_tag, biz_status, order_field_meta
- Computed: storeGroups, storeZtaiGroups, defaultStore, operOptions, noteTagOptions, bizStatusOptions
- Flags: loading, error
- Actions:
- fetchDictData: parallel fetch of dictionary and biz_status, then compute derived options and groups
Diagram sources
Section sources
Local Store: useSitePromotionStore
- Purpose: Persist and hydrate search filters for site-wide promotions across browser sessions.
- State slices:
- productSearch: selectedStore, dateRange, statusFilter, planNameSearch, planGroupFilter
- storeSearch: selectedStore, dateRange, statusFilter
- promotionType: 'product' | 'store'
- _hasHydrated: hydration flag
- Persistence:
- Uses Zustand persist with localStorage
- Partializes state to persist only relevant slices
- onRehydrateStorage sets hydration flag
Diagram sources
Section sources
API State Management
- Typed endpoints: initBi, setOperQuickMenu, analysisPreview, getHomeData/setHomeData, templates, categories, order fields, formulas.
- Request utilities:
- Interceptors for token injection and 401 handling
- Environment-aware routing (gateway vs rewrite)
- Timeout control and response parsing
- Optimistic updates:
- toggleQuickMenu optimistically updates quickMenus before confirming with API
- refreshMenu replaces menu list after successful fetch
Diagram sources
Section sources
Integration Between Global Stores and Local Component State
- Components subscribe to Zustand stores for cross-cutting concerns (auth, menus, favorites).
- Local component state (e.g., form inputs, temporary UI flags) uses React hooks.
- Hooks can combine both global and local state to coordinate UI behavior.
Examples of local state patterns (conceptual):
- Form inputs: useState for transient values, submit triggers store actions
- UI flags: useState for visibility, disabled states, and temporary messages
- Selections: useState for component-local selections, synchronized with global store via actions
[No sources needed since this section doesn't analyze specific files]
Dependency Analysis
- Stores depend on API module for data fetching and on request utilities for HTTP operations.
- useCommonStore depends on multiple API endpoints executed in parallel.
- useSitePromotionStore depends on React lifecycle and localStorage for persistence.
- API module depends on request utilities for transport and environment configuration.
Diagram sources
Section sources
Performance Considerations
- Minimize store updates: batch updates with a single set call when possible
- Avoid unnecessary re-renders: keep state flat; split stores by domain to reduce selector scope
- Selective persistence: use partialize to persist only necessary slices (as in useSitePromotionStore)
- Parallelize API calls: useCommonStore executes multiple endpoints concurrently
- Guard repeated initialization: useBiStore checks initialized/loading flags before proceeding
- Derived computations: compute derived options once per data load (as in useCommonStore)
- Request timeouts and retries: configure timeouts in request utilities; consider adding retry logic at the API layer if needed
[No sources needed since this section provides general guidance]
Troubleshooting Guide
- Initialization failures:
- Check useBiStore initBiData error handling and logging
- Verify API endpoint availability and response shape
- Token expiration:
- Default error interceptor handles 401; ensure tokens are stored and refreshed appropriately
- Hydration issues:
- Confirm onRehydrateStorage sets hydration flag and partialize includes intended fields
- Network errors:
- Inspect request utilities for timeout, network exceptions, and environment routing
Section sources
Conclusion
The project employs a pragmatic state management architecture:
- Global state is centralized in Zustand stores with clear separation of concerns
- Local component state is handled via React hooks for UI-specific transient data
- API state management is strongly typed and routed through a unified request utility with robust interceptors
- Persistence and hydration are implemented selectively for local slices
- The design supports optimistic updates, parallel data fetching, and guarded initialization for reliability