Architecture & State Store Design (Store Pattern)0%

Architecture & State Store Design (Store Pattern)

Beginner12 min read•Updated: Jul 11, 2026
Study Materials

Capstone Part 1: Architecture & State Store Design

In enterprise-scale frontend engineering, managing application state across dozens of decoupled components without prop-drilling or state divergence requires a centralized, predictable State Store Architecture. In this first capstone lesson, you will build a reactive, production-grade Store Engine implementing the Redux/Zustand pattern with immutable state updates, middleware pipelines, and subscriptions.


1. The Unidirectional Data Flow Architecture

Output
┌────────────────────────────────┐
│ UI Component (View) │
└───────────────┬────────────────┘
│ dispatch(action)
▼
┌────────────────────────────────┐
│ Middleware Pipeline │ (Logging, Crash Telemetry, Persistence)
└───────────────┬────────────────┘
│
▼
┌────────────────────────────────┐
│ Reducer Function │ (Pure function: (state, action) => newState)
└───────────────┬────────────────┘
│
▼
┌────────────────────────────────┐
│ Central Store State │
└───────────────┬────────────────┘
│ notify subscribers
▼
┌────────────────────────────────┐
│ Subscribed UI Components │ (Re-render with fresh selector data!)
└────────────────────────────────┘

2. Implementing the Store Core

JavaScript
class Store {
#state;
#reducer;
#subscribers = new Set();
#middlewares = [];
 
constructor(reducer, initialState, middlewares = []) {
this.#reducer = reducer;
this.#state = Object.freeze({ ...initialState });
this.#middlewares = middlewares;
}
 
// Read current state immutably
getState() {
return this.#state;
}
 
// Subscribe to state changes (returns unsubscribe function)
subscribe(listener) {
this.#subscribers.add(listener);
return () => this.#subscribers.delete(listener);
}
 
// Dispatch an action through middleware to the reducer
dispatch(action) {
if (!action || typeof action.type !== 'string') {
throw new TypeError('Actions must be objects with a string "type" property.');
}
 
// Execute middleware chain
const runMiddleware = (index) => {
if (index < this.#middlewares.length) {
const middleware = this.#middlewares[index];
middleware(this, action, () => runMiddleware(index + 1));
} else {
// Reducer execution after all middleware complete
const nextState = this.#reducer(this.#state, action);
this.#state = Object.freeze({ ...nextState });
 
// Notify all subscribers
this.#subscribers.forEach(listener => listener(this.#state));
}
};
 
runMiddleware(0);
}
}

3. Implementing Logging & LocalStorage Middleware

JavaScript
// Middleware 1: Action Logger
const loggerMiddleware = (store, action, next) => {
console.group(`[Action]: ${action.type}`);
console.log('Previous State:', store.getState());
console.log('Payload:', action.payload);
next(); // Pass to next middleware
console.log('Next State:', store.getState());
console.groupEnd();
};
 
// Middleware 2: Persistent Storage Sync
const storageSyncMiddleware = (store, action, next) => {
next(); // Run reducer first
localStorage.setItem('app_state_backup', JSON.stringify(store.getState()));
};

4. Reducer & Selectors

JavaScript
// Initial State
const initialAppState = {
user: { name: 'Elena', role: 'admin' },
notifications: [],
theme: 'dark'
};
 
// Pure Reducer Function
function appReducer(state, action) {
switch (action.type) {
case 'THEME_TOGGLE':
return { ...state, theme: state.theme === 'dark' ? 'light' : 'dark' };
 
case 'NOTIFICATION_ADD':
return {
...state,
notifications: [...state.notifications, action.payload]
};
 
case 'NOTIFICATION_CLEAR':
return { ...state, notifications: [] };
 
default:
return state;
}
}
 
// Selectors for targeted state queries
const selectTheme = state => state.theme;
const selectNotificationCount = state => state.notifications.length;

5. Usage & Verification

JavaScript
const store = new Store(appReducer, initialAppState, [loggerMiddleware, storageSyncMiddleware]);
 
// Subscribe component listener
const unsubscribe = store.subscribe((newState) => {
console.log('UI Render triggered! Current Theme:', selectTheme(newState));
});
 
// Dispatch actions
store.dispatch({ type: 'THEME_TOGGLE' });
store.dispatch({
type: 'NOTIFICATION_ADD',
payload: { id: 1, text: 'Backup completed successfully.' }
});
 
// Unsubscribe when component unmounts
unsubscribe();

Interactive Quiz

Practice Quiz

Question 1
What is the role of a Reducer in a unidirectional state store architecture?
Question 2
Why is the state object frozen with Object.freeze() inside the Store?
Question 3
What is the responsibility of Middleware in a state store?
Question 4
Why do store.subscribe() methods return an unsubscribe function?
Question 5
What is a "Selector" in modern state management?
Next Lesson

Real-Time Collaborative Dashboard Engine

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext