react • 29 May 2024
React's built-in state management works for small apps, but complex ones need more. State management libraries offer a centralized solution, improving scalability and reducing complexity. However, building your own library can be advantageous for specific situations. You can tailor it to your application's needs, potentially improving efficiency and code clarity. This can also be a valuable learning experience.
Today we will learn how to make how to make our own React State Management.
function createStore<T>({ initialState }: { initialState: T }) { let subscribers: Listener[] = []; let state = initialState; const notifyStateChanged = () => { subscribers.forEach((fn) => fn()); }; return { subscribe(fn: Listener) { subscribers.push(fn); return () => { subscribers = subscribers.filter((listener) => listener !== fn); }; }, getSnapshot() { return state; }, setState(newState: T) { state = newState; notifyStateChanged(); }, }; }
To use the store in react we'll create createUseStore which is a helper that wraps createStore and useSyncExternalStore in a convenient way:
export function createUseStore<T>(initialState: T) { const store = createStore({ initialState }); return () => [useSyncExternalStore(store.subscribe, store.getSnapshot), store.setState] as const; }
export const useCountStore = createUseStore(0);
import { useCountStore } from "./countStore"; function Counter() { const [count, setCount] = useCountStore(); const increment = () => { setCount(count + 1); }; const decrement = () => { setCount(count - 1); }; return ( <div> <p>Count: {count}</p> <button onClick={increment}>Increment</button> <button onClick={decrement}>Decrement</button> </div> ); }
Read more about useSyncExternalStore in the react docs.
To see the implementation of the concepts discussed in this article in action, check out tinystate-react. This library is built using the approach described in this tutorial, allowing you to dive deeper into the code and examples.