Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Hacky hooks to help you solve certain performance issues with minimal fuss; e.g. `<Foo bar={[1, 2, 3]} />` passes a new array every time, but `useDynamicToStatic` can be used to treat it as if it were the same array so as to not trigger further hook's update methods.
/*
* If you're sent a dynamic value but you want to treat it as static (e.g. for
* hook dependencies), you can use this function. For arrays it will compare the
* contents of the array rather than the array object itself. For objects it
* will compare the keys and values of the object, rather than the object
* itself. For functions it will just replace the function with a static
* function that calls the underlying function using references.
*/
export function useDynamicToStatic<T>(value: T) {
let condition = [];
let memo = () => value;
const ref = useRef(value);
ref.current = value;
if (Array.isArray(value)) {
condition = ["array", ...value];
} else if (typeof value === "function") {
// @ts-ignore
memo = () => (...args: any[]) => {
// @ts-ignore
ref.current(...args);
};
condition = ["function"];
} else if (value) {
condition = ["object", ...flatten([...Object.entries(value)])];
}
// eslint-disable-next-line react-hooks/exhaustive-deps
return useMemo<T>(memo, condition);
}
/*
* Pass a _STATICALLY SHAPED_ object to this hook to log out which properties
* changed on each render (e.g. to debug why hooks are being called).
*
* e.g. `useWhatChanged({ var1, var2, var3 });
*/
export function useDebugWhatChanged(props: any) {
const keys = Object.keys(props);
for (const key of keys) {
// eslint-disable-next-line
useEffect(() => {
console.log(`${key} CHANGED`);
}, [key]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment