const createStoreImpl: CreateStoreImpl = (createState) => { type TState = ReturnType<typeof createState> type Listener = (state: TState, prevState: TState) => void let state: TState const listeners: Set<Listener> = new Set() const setState: StoreApi<TState>['setState'] = (partial, replace) => { // TODO: Remove type assertion once https://github.com/microsoft/TypeScript/issues/37663 is resolved // https://github.com/microsoft/TypeScript/issues/37663#issuecomment-759728342 const nextState = typeof partial === 'function' ? (partial as (state: TState) => TState)(state) : partial if (!Object.is(nextState, state)) { const previousState = state state = (replace ?? (typeof nextState !== 'object' || nextState === null)) ? (nextState as TState) : Object.assign({}, state, nextState) listeners.forEach((listener) => listener(state, previousState)) } } const getState: StoreApi<TState>['getState'] = () => state const getInitialState: StoreApi<TState>['getInitialState'] = () => initialState const subscribe: StoreApi<TState>['subscribe'] = (listener) => { listeners.add(listener) // Unsubscribe return () => listeners.delete(listener) } const api = { setState, getState, getInitialState, subscribe } const initialState = (state = createState(setState, getState, api)) return api as any}
In our previous articles, I have written about how setState, subscribe work. We will cover the remaining functions such as getState, getInitialState, createState.
createState is a parameter in createStoreImpl. Let’s run some experiments using the demo example provided in the Zustand’s repo.
This is basically just what you pass into “create”
// Create the store using Zustandconst useStore = create((set) => ({ count: 1, inc: () => set((state) => ({ count: state.count + 1 })),}));
State initialisation happens in vanilla.ts at L93, even though create is originally exported from React, react.ts internally calls createStore in vanilla.ts.
So how does calling createState initializes the state?
The trick lies in calling the arrow function, createState. From the above code snippet, you can see that createState is called with setState, getState, api
Let’s run some experiments with this information. Let’s pass a custom function named test as the parameter without the original parameters.
The above image shows the custom test function I added to demonstrate how the parameters are passed to createState function.
let’s now see this internal test function in action. For us to access this test function, the following example shows how createStore can be initialised with this newly added test parameter.
Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.