Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Hooks, how to prevent unnecessary rerendering

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.

like image 645
yangli-io Avatar asked Feb 03 '26 02:02

yangli-io


1 Answers

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

like image 145
rycha Avatar answered Feb 04 '26 16:02

rycha