Skip to content

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

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. 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