State Management Strategy
Relevant source files
The following files were used as context for generating this wiki page:
The Wasalny landing page employs a multi-layered state management strategy designed for a high-performance React 19 application. It leverages localized component state, custom hooks for complex business logic, and React Context for global UI settings like theming.
The strategy focuses on maintaining reactivity across interactive components—such as the pricing calculator and theme switcher—while ensuring persistence through browser storage where necessary.
Global State: Theme Management
Global state is primarily managed using the React Context API to handle the application's visual theme. This ensures that the user's preference (light, dark, or system) is accessible throughout the component tree without prop drilling.
ThemeContext Architecture
The ThemeContext provides three key values: the current theme setting, a setTheme function, and a resolvedTheme (which translates 'system' into either 'light' or 'dark').
The implementation uses a useCallback to apply CSS classes to the document root, ensuring that Tailwind's dark: variants are triggered correctly.
Sources: src/context/ThemeContext.tsx:1-60, src/App.tsx:25-50
Local and Persistent Business Logic: Pricing Calculator
The most complex state management occurs within the pricing calculator. This is handled via a custom hook, usePricingCalculator, which orchestrates UI state, derived computations, and persistence to localStorage.
Data Flow and Synchronization
The calculator manages multiple interdependent state variables, such as route types, locations, and passenger counts. It uses useEffect hooks to synchronize these values (e.g., resetting "To" locations if the "From" location changes).
| State Property | Description | Persistence |
|---|---|---|
routeType | 'travel' or 'internal' | Yes |
vehicleCategory | Selected vehicle type | Yes |
passengerCount | Number of passengers | Yes |
fromLocation | Starting point ID | No |
toLocation | Destination ID | No |
isRoundTrip | Toggle for return trip | No |
Lifecycle and UI State
The application manages ephemeral UI states such as loading transitions and visibility triggers for floating elements.
Loading State
The App component maintains an isLoading state which controls the display of the PageLoader. This state is updated via a callback passed to the loader component once its GSAP animations complete.
Scroll-Triggered Visibility
Components like the FloatingCTA manage their own visibility state by listening to scroll events via ScrollTrigger. This allows the UI to react to the user's position on the page without cluttering the global state.
Persistence Strategy
Persistence is utilized to enhance user experience by remembering preferences across sessions.
- Theme Persistence: Stored under the key
wasalny-theme. It is initialized during the state setup inThemeContext. - Calculator Persistence: Stored under
wasalny_pricing_v2. TheusePricingCalculatorhook loads this state on mount and saves it whenever relevant configuration values (route, vehicle, passengers) change.
Sources: src/context/ThemeContext.tsx:16-25, src/hooks/usePricingCalculator.ts:102-125
Summary
The project utilizes a decentralized state management approach. React Context handles cross-cutting concerns like UI theming. Custom Hooks encapsulate complex business logic and computation for the pricing system. GSAP/ScrollTrigger managed states handle the interactive visual lifecycle of the landing page, ensuring that state changes are fluid and performant.