Search code examples
javascriptreactjsreact-hooks

Why is my component re-rendering even though custom hook values aren't changing?


I'm working with nested custom hooks in React, and I'm experiencing an unexpected re-render in my parent component, even though the value returned from one of the custom hooks remains unchanged. Specifically, the useIsAdmin hook depends on the session data from useSession, but even when the session's roles don't change, the parent component re-renders.

Here’s a simplified version of my code:

// Custom hook to check if user is admin
export const useIsAdmin = () => {
  const { data: session } = useSession(); // Fetch session data

  // Check if the user's roles match the required admin roles
  return useMemo(
    () =>
      ADMIN_READ.every((role) =>
        session?.roles?.find((userRole) => userRole === role)
      ),
    [session?.roles]
  );
};

Issue:

The useIsAdmin hook is the middle custom hook. Each time useSession fetches the session, even though the session.roles value remains the same, the parent component still re-renders. I expected the useMemo to prevent re-renders as long as session.roles hasn’t changed.

What I’ve tried:

  • I've checked if the roles are deeply equal but the re-render happens regardless.
  • Tried using React.memo for the parent component to prevent unnecessary re-renders, but it still occurs.
  • Verified that session.roles remains identical between renders.

Question:

Why is the parent component re-rendering even though useIsAdmin's result doesn't change when session.roles is the same? Is there a problem with how I’m using useSession or useMemo in this nested hook setup?

Additional Info:

  • I'm using React v18.3.1
  • The parent component re-renders whenever useSession fetches data, despite session.roles being unchanged.

Want to prevent the component rerendering whenever last child custom hook return same data


Solution

  • I've checked if the roles are deeply equal but the re-render happens regardless.

    React renders when the state changes reference. Deep equality isn't important here; if you're creating a new array with the same values, that will trigger a re-render.

    It would help to see what your useSession hook looks like.