Skip to content

Instantly share code, notes, and snippets.

@carefree-ladka
Created December 9, 2024 09:35
Show Gist options
  • Save carefree-ladka/0967b18d17cb2cb203ac17d74e51b16e to your computer and use it in GitHub Desktop.
Save carefree-ladka/0967b18d17cb2cb203ac17d74e51b16e to your computer and use it in GitHub Desktop.
Custom Redux Implementation with Custom Middleware
// Redux Store Implementation with Middleware Support
function createStore(reducer, middleware) {
let state;
let listeners = [];
// Get the current state
const getState = () => state;
// Dispatch an action (placeholder, replaced later with middleware logic)
let dispatch = (action) => {
state = reducer(state, action);
listeners.forEach((listener) => listener());
};
// Subscribe to state changes
const subscribe = (listener) => {
listeners.push(listener);
return () => {
listeners = listeners.filter((l) => l !== listener);
};
};
// Apply middleware to enhance dispatch
if (middleware) {
const middlewareAPI = { getState, dispatch: (action) => dispatch(action) };
dispatch = middleware(middlewareAPI)(dispatch);
}
// Initialize the state
dispatch({ type: "@@INIT" });
return { getState, dispatch, subscribe };
}
// Logger Middleware Example
const loggerMiddleware = ({ getState }) => (next) => (action) => {
console.log("Dispatching:", action);
next(action); // Proceed with action
console.log("Next state:", getState());
};
// Example Reducer with Payload Handling
function counterReducer(state = { count: 0 }, action) {
switch (action.type) {
case "INCREMENT_BY":
return { count: state.count + action.payload.value };
case "SET_COUNT":
return { count: action.payload.value };
case "RESET":
return { count: 0 };
default:
return state;
}
}
// Usage Example
const store = createStore(counterReducer, loggerMiddleware);
// Subscribe to State Changes
const unsubscribe = store.subscribe(() => {
console.log("State changed:", store.getState());
});
// Dispatch Actions with Payload
store.dispatch({ type: "INCREMENT_BY", payload: { value: 5 } }); // Dispatching: { count: 5 }
store.dispatch({ type: "SET_COUNT", payload: { value: 10 } }); // Dispatching: { count: 10 }
store.dispatch({ type: "RESET" }); // Dispatching: { count: 0 }
// Unsubscribe Listener
unsubscribe();
// Further Dispatches Won't Trigger Subscriptions
store.dispatch({ type: "INCREMENT_BY", payload: { value: 3 } }); // Only logs due to middleware
/*
Dispatching: { type: '@@INIT' }
Next state: { count: 0 }
Dispatching: { type: 'INCREMENT_BY', payload: { value: 5 } }
State changed: { count: 5 }
Next state: { count: 5 }
Dispatching: { type: 'SET_COUNT', payload: { value: 10 } }
State changed: { count: 10 }
Next state: { count: 10 }
Dispatching: { type: 'RESET' }
State changed: { count: 0 }
Next state: { count: 0 }
Dispatching: { type: 'INCREMENT_BY', payload: { value: 3 } }
Next state: { count: 3 }
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment