i am using zustand to store templates, which is a multi-dimension array, and i have created a function to get value from store in single hit.
Why, i am doing this way is because i am not want to write a state-picks every time i need something from state like.
const template = useStoreName((state) => state.template))
and so on….
so i come up with the solution( as i think this is solution) crate a function which is responsible for accept store ref, and keys which i want to get from store.
here are functions
export function createSelectorHook<
TStore extends StoreApi<any>,
TKeys extends keyof ExtractState<TStore>,
>(
store: TStore,
keys: TKeys[],
equalityFn?: <K extends TKeys>(
a: ExtractState<TStore>[K],
b: ExtractState<TStore>[K],
) => boolean = Object.is,
): Pick<ReturnType<TStore['getState']>, TKeys> {
const selections = {} as Pick<ReturnType<TStore['getState']>, TKeys>;
keys.forEach(key => {
selections[key] = useStoreWithEqualityFn(store, s => s[key], equalityFn);
});
return selections;
}
this is responsible for retrun store value in object
i use this in this way like
const {template, count} = createSelectorHook(storeRefrence, ['template', 'count'])
i know i am Violating React Hook rules
Why, i create below function is my requirement for render purpose is to direct get template data from index, so i use dotted string to store where they belong
i have another function which is responsible for getting value from store through dotted string.
export function useGetSelectorByPathHook<TStore extends StoreApi<any>, TKeys extends string>(
store: TStore,
keys: TKeys,
equalityFn: <K extends TKeys>(
a: ExtractState<TStore>[K],
b: ExtractState<TStore>[K],
) => boolean = Object.is,
): Record<TKeys, any> | any {
// return useStore(store, state => getValueAtPath(state, keys));
const render = useStoreWithEqualityFn(store, state => getValueAtPath(state, keys), equalityFn);
return render;
}
function getValueAtPath(obj: any, path: string) {
return path.split('.').reduce((acc, part) => {
if (acc === undefined || acc === null) return undefined;
return acc[part];
}, obj);
}
i use this function like
const layout = useGetSelectorByPathHook(storeRef, 'template.0.layout.1')
I just want confirmation that it is a write way to do that am i doing, or i am violating any rule of zustand or react or it make problem in future.
or there could be problem for memoization level if i am using this.
any suggestion or improvements will help me to do it in better way.