Skip to main content

State Management

High-level overview of state management architecture in AquaGen using React Context.


Overview

AquaGen uses React Context API for state management across the application.

Two-Level Architecture:

  1. Global State - AppStore (application-wide)
  2. Feature State - Feature-specific stores (per library)

Location:

  • Global: libs/shared/src/store/AppStore.js
  • Features: libs/{feature-name}/src/store/

AppStore (Global State)

Purpose

Central store for application-wide state shared across all features.

Managed State

StateTypePurpose
loginDataObjectUser authentication data
selectedCategoryStringCurrent selected category
selectedNavOptionObjectCurrent navigation option
sideBarOpenBooleanSidebar open/closed state
menuIconEnabledBooleanMenu icon visibility
constantDateDateGlobal date filter
constantDateTypeStringDate type selection
landingPageFeaturePopupBooleanFeature popup state
subscriptionDataObjectSubscription information

Key Methods

  • setLoginData() - Update login data
  • handleLogout() - Logout user
  • setSelectedCategory() - Set active category
  • setSideBarOpen() - Toggle sidebar

Usage

import { useContext } from 'react';
import { AppStoreContext } from '@aquagen-mf-webapp/shared/store/AppStore';

function MyComponent() {
const appStore = useContext(AppStoreContext);

// Access state
const user = appStore.loginData;
const isOpen = appStore.sideBarOpen;

// Update state
appStore.setSideBarOpen(true);
appStore.setSelectedCategory('dashboard');
}

Code Reference: libs/shared/src/store/AppStore.js:1-179


Feature Stores

Purpose

Each feature library has its own store for feature-specific state.

Available Feature Stores

  • DashboardStore - Dashboard data
  • MonitoringStore - Water monitoring data
  • EnergyStore - Energy consumption data
  • AlertsStore - Alerts and notifications
  • WaterBalanceStore - Water balance data
  • AquaGPTStore - AI chat state
  • And 15+ more...

Pattern

Each feature store follows the same pattern:

// 1. Create Context
const FeatureContext = createContext();

// 2. Provider Component
function FeatureProvider({ children }) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);

return (
<FeatureContext.Provider value={{ data, setData, loading }}>
{children}
</FeatureContext.Provider>
);
}

// 3. Custom Hook
export const useFeature = () => useContext(FeatureContext);

Usage Example

import { useDashboard } from '@aquagen-mf-webapp/dashboard/store';

function DashboardWidget() {
const { dashboardData, loading } = useDashboard();

if (loading) return <Loader />;
return <Display data={dashboardData} />;
}

State Flow


Best Practices

  1. Use AppStore for global state - Authentication, navigation, etc.
  2. Use Feature Stores for feature data - Keep feature state isolated
  3. Avoid prop drilling - Use context instead of passing props deeply
  4. Keep state minimal - Only store what's needed globally
  5. Use custom hooks - useFeature() pattern for cleaner code

Provider Hierarchy

<AppStoreProvider>           {/* Global state */}
<DashboardProvider> {/* Feature state */}
<DashboardPage />
</DashboardProvider>
</AppStoreProvider>

Next Steps


Last Updated: February 2026