Overview
Web XP uses React’suseReducer hook for centralized state management. This pattern provides predictable state updates through dispatched actions, similar to Redux but with less boilerplate.
Implementation: src/WinXP/index.jsx:55 and src/WinXP/reducer.js:1
The useReducer Pattern
The WinXP component initializes state with:state: The current state objectdispatch: Function to dispatch actions to update state
Initial State
The initial state is defined insrc/WinXP/reducer.js:18:
State Shape
apps
Array of open application instances:icons
Array of desktop icons:focusing
Indicates what element type currently has focus:src/WinXP/constants/index.js:1
selecting
Drag-to-select state:powerState
Current power operation state:src/WinXP/constants/index.js:6
Action Types
All action types are defined insrc/WinXP/constants/actions.js:1:
Reducer Implementation
The reducer is defined insrc/WinXP/reducer.js:28:
Dispatching Actions
Actions are dispatched throughout the WinXP component:Adding an Application
src/WinXP/index.jsx:149
Closing an Application
src/WinXP/index.jsx:108
Focusing an Application
src/WinXP/index.jsx:96
Minimizing an Application
src/WinXP/index.jsx:104
Toggling Maximize
src/WinXP/index.jsx:100
Focusing an Icon
src/WinXP/index.jsx:124
Selecting Multiple Icons
src/WinXP/index.jsx:207
Focusing Desktop
src/WinXP/index.jsx:135
Starting Drag-Select
src/WinXP/index.jsx:196
Ending Drag-Select
src/WinXP/index.jsx:203
Power Operations
src/WinXP/index.jsx:174 and src/WinXP/index.jsx:177
Action Details
ADD_APP
Adds a new application window or focuses an existing single-instance app: Logic:- Check if app already exists and is single-instance
- If exists and single-instance: bring to front and restore
- If new or multi-instance: create new app with unique ID
- Increment
nextAppIDandnextZIndex - Set
focusingtoFOCUSING.WINDOW
src/WinXP/reducer.js:30
DEL_APP
Removes an application and updates focus: Logic:- Filter out app with matching ID
- If remaining apps exist: set
focusingtoFOCUSING.WINDOW - Else if focused icons exist: set
focusingtoFOCUSING.ICON - Else: set
focusingtoFOCUSING.DESKTOP
src/WinXP/reducer.js:64
FOCUS_APP
Brings an app window to the front: Logic:- Find app with matching ID
- Set app’s
zIndextonextZIndex - Set app’s
minimizedtofalse - Increment
nextZIndex - Set
focusingtoFOCUSING.WINDOW
src/WinXP/reducer.js:78
MINIMIZE_APP
Minimizes an application window: Logic:- Find app and set
minimizedtotrue - If other non-minimized apps exist: set
focusingtoFOCUSING.WINDOW - Else if focused icons exist: set
focusingtoFOCUSING.ICON - Else: set
focusingtoFOCUSING.DESKTOP
src/WinXP/reducer.js:91
TOGGLE_MAXIMIZE_APP
Toggles window maximized state: Logic:- Find app and toggle
maximizedboolean - Set
focusingtoFOCUSING.WINDOW
src/WinXP/reducer.js:108
FOCUS_ICON
Focuses a single desktop icon: Logic:- Set
isFocustotruefor matching icon - Set
isFocustofalsefor all other icons - Set
focusingtoFOCUSING.ICON
src/WinXP/reducer.js:118
SELECT_ICONS
Focuses multiple icons (from drag-select): Logic:- Set
isFocustotruefor icons in payload array - Set
isFocustofalsefor all other icons - Set
focusingtoFOCUSING.ICON
src/WinXP/reducer.js:129
FOCUS_DESKTOP
Clears all icon focus: Logic:- Set
isFocustofalsefor all icons - Set
focusingtoFOCUSING.DESKTOP
src/WinXP/reducer.js:140
START_SELECT
Begins drag-to-select operation: Logic:- Set
isFocustofalsefor all icons - Set
selectingto payload position{ x, y } - Set
focusingtoFOCUSING.DESKTOP
src/WinXP/reducer.js:149
END_SELECT
Ends drag-to-select operation: Logic:- Set
selectingtonull
src/WinXP/reducer.js:159
POWER_OFF
Shows power operation dialog: Logic:- Set
powerStateto payload (POWER_STATE.LOG_OFForPOWER_STATE.TURN_OFF)
src/WinXP/reducer.js:164
CANCEL_POWER_OFF
Closes power operation dialog: Logic:- Set
powerStatetoPOWER_STATE.START
src/WinXP/reducer.js:169
Benefits of This Pattern
Predictable State Updates
All state changes go through the reducer, making it easy to trace how state changes in response to actions.Centralized Logic
Complex state update logic is centralized in the reducer rather than scattered throughout components.Easy Debugging
You can log actions and state to see exactly what happened:Testable
Reducer is a pure function that’s easy to test:Comparison to useState
Instead of managing multipleuseState calls:
