Skip to content

Instantly share code, notes, and snippets.

@mustafadalga
Created November 10, 2024 16:03
Show Gist options
  • Save mustafadalga/b9dea62dd6eface32c65a9cdd166ebc8 to your computer and use it in GitHub Desktop.
Save mustafadalga/b9dea62dd6eface32c65a9cdd166ebc8 to your computer and use it in GitHub Desktop.
Building a Custom JavaScript State Management Library Inspired by Zustand
interface User {
_id: string;
name: string;
}
interface State {
users: User[];
addUser: (user: User) => void;
removeAllUsers: () => void;
}
function create<T>(setupFunction: (set: (updater: ((state: T) => Partial<T>) | Partial<T>) => void) => T) {
// Initial state of the store
let state: T = {} as T;
// Listeners array to store subscriber functions
const listeners: (() => void)[] = [];
// The 'set' function that allows state updates
const set = (updater: ((state: T) => Partial<T>) | Partial<T>) => {
const nextState = typeof updater === 'function' ? updater(state) : updater;
state = { ...state, ...nextState }; // Merge the new state with the current state
notifyListeners(); // Notify all listeners about the state change
};
// Function to notify all listeners/subscribers
const notifyListeners = () => {
listeners.forEach(listener => listener());
}
// Subscribe function to add new listeners
const subscribe = (listener: () => void) => {
listeners.push(listener);
return () => { // Return an unsubscribe function
const index = listeners.indexOf(listener);
if (index > -1) listeners.splice(index, 1);
};
};
// Initialize the store using the setup function, which defines the state and methods
state = setupFunction(set);
// Return the public API of the store
return {
getState: () => state,
subscribe,
};
}
// Usage example
export const useUsersStore = create<State>((set) => ({
users: [],
addUser: (user) => set(state => ({ users: [ ...state.users, user ] })),
removeAllUsers: () => set({ users: [] }),
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment