createWithEqualityFnImpl in Zustand source code explained.
In this article, we will analyse how the createWithEqualityFnImpl is implemented by logging some of its value to get a better understanding.
As you can tell from the above image, createWithEqualityFn calls the function createWithEqualityFnImpl. This pattern is used in vanilla.ts as well as demonstrated below:
export const createStore = ((createState) =>
createState ? createStoreImpl(createState) : createStoreImpl) as CreateStore
createStore calls createStoreImpl and createWithEqualityFn calls createWithhEqualityFnImpl.
Before we jump into the execution of createWithEqualityFn, let’s first understand the purpose of using createWithEqualityFn.
The above screenshot is from https://github.com/pmndrs/zustand/tree/main
You can use createWithEqualityFn to have more control over re-rendering.
createWithEqualityFn
const createWithEqualityFnImpl = <T>(
createState: StateCreator<T, [], []>,
defaultEqualityFn?: <U>(a: U, b: U) => boolean,
) => {
const api = createStore(createState)
const useBoundStoreWithEqualityFn: any = (
selector?: any,
equalityFn = defaultEqualityFn,
) => useStoreWithEqualityFn(api, selector, equalityFn)
Object.assign(useBoundStoreWithEqualityFn, api)
return useBoundStoreWithEqualityFn
}
useStoreWithEqualityFn
export function useStoreWithEqualityFn<S extends ReadonlyStoreApi<unknown>>(
api: S,
): ExtractState<S>
export function useStoreWithEqualityFn<S extends ReadonlyStoreApi<unknown>, U>(
api: S,
selector: (state: ExtractState<S>) => U,
equalityFn?: (a: U, b: U) => boolean,
): U
export function useStoreWithEqualityFn<TState, StateSlice>(
api: ReadonlyStoreApi<TState>,
selector: (state: TState) => StateSlice = identity as any,
equalityFn?: (a: StateSlice, b: StateSlice) => boolean,
) {
const slice = useSyncExternalStoreWithSelector(
api.subscribe,
api.getState,
api.getInitialState,
selector,
equalityFn,
)
useDebugValue(slice)
return slice
}
This is an overloading function. useStoreWithEqualityFn has 3 definitions:
export function useStoreWithEqualityFn<S extends ReadonlyStoreApi<unknown>>(
api: S,
): ExtractState<S>
export function useStoreWithEqualityFn<S extends ReadonlyStoreApi<unknown>, U>(
api: S,
selector: (state: ExtractState<S>) => U,
equalityFn?: (a: U, b: U) => boolean,
): U
export function useStoreWithEqualityFn<TState, StateSlice>(
api: ReadonlyStoreApi<TState>,
selector: (state: TState) => StateSlice = identity as any,
equalityFn?: (a: StateSlice, b: StateSlice) => boolean,
) {
Let’s see how the slice value looks like:
value: 1 is skipped because we set the code to avoid re-render when the value is 1 as shown below:
About us:
At Think Throo, we are on a mission to teach the best practices inspired by open-source projects.
10x your coding skills by practising advanced architectural concepts in Next.js/React, learn the best practices and build production-grade projects.
We are open source — https://github.com/thinkthroo/thinkthroo (Do give us a star!)
Up skill your team with our advanced courses based on codebase architecture. Reach out to us at hello@thinkthroo.com to learn more!