I have a hook that gets data from another hook
const useIsAdult = () => {
const data = useFormData();
return data.age > 18;
}
This hook returns true or false only, however the useFormData is constantly being updated. Everytime useFormData reruns, it will rerender my component. I only want my component to rerender if the result of useIsAdult changes.
I know this can obviously be solved by implementing some logic via react-redux and using their useSelector to prevent rendering, but I'm looking for a more basic solution if there is any.
Before you say useMemo, please read question carefully. The return value is a boolean, memo here doesnt make any sense.
Even with returned useMemo in useIsAdult parent component will be rerendered. This problem is reason why I rarely create custom hooks with other hooks dependency. It will be rerender hell.
There I tried to show that useMemo doesnt work. And using useMemo for components its wrong way. For components we have React.memo.
const MyComponent = memo(({ isAdult }: { isAdult: boolean }) => {
console.log("renderMy");
return <h1>Hello CodeSandbox</h1>;
});
And memo will help to prevent rendering of MyComponent. But parent component still render.
https://codesandbox.io/s/interesting-lumiere-xbt4gg?file=/src/App.tsx
If you can modify useFormData maybe useRef can help. You can store data in useRef but it doesnt trigger render.
Something like this but in useFormData:
onst useIsAdult = () => {
const data = useFormData();
const prevIsAdultRef = useRef();
const isAdult = useMemo(() => data.age > 18, [data]);
if (prevIsAdultRef.current === isAdult) {
return prevIsAdultRef.current;
}
prevIsAdultRef.current = isAdult;
return isAdult;
};
I dont know how useFormData works, then you can try it self with useRef.
And if useFormData gets data very often and you cant manage this, you can use debounce or throttle to reduce number of updates
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With