PROBLEM
Why my parent component is re-rendered if my child uses a hook that consumes a context?
CODE
I have read on GitHub, that for preventing the re-renders of components which use hooks that consume contexts, it is a good option to do the following:
function UserPosts({ contents, userData }) {
const bottomSheet = usePostBottomSheet();
return (
<MemoizedUserPosts
contents={contents}
userData={userData}
bottomSheet={bottomSheet}
/>
);
}
function areUserPostsPropsEqual() {
return true;
}
const MemoizedUserPosts = memo(({ contents, userData, bottomSheet }) => {
console.log("Re-rendering", userData.name, "user posts");
const { locale, t } = useLanguage();
const isMounted = useIsMounted();
...
return (
<CardList
data={posts}
...
/>
);
}, areMemoizedUserPostsPropsEqual);
function areMemoizedUserPostsPropsEqual() {
return true;
}
As you can see, in my MemoizedUserPosts, I am only using two hooks, which doesn't re-render the component.
When I pass the data to the CardList, I am rendering Cards. This Card component renders my AuthorRow component, which is causing the re-render of "MemoizedUserPosts" because of using a hook that consumes my Users Context:
export default function AuthorRow({ userData, onOptionsButtonPress }) {
// Get the most updated user data from the users contexts
const updatedUserData = useUpdatedUserData(userData); <---- THIS LINE
return (
<MemoizedAuthorRow
userData={updatedUserData}
onOptionsButtonPress={onOptionsButtonPress}
/>
);
}
If I delete that line, then the MemoizedUserPosts is not re-rendered when the userData changes in my context.
Here is my useUpdatedUserData hook:
export default function useUpdatedUserData(userData) {
const currentUser = useCurrentUser(); <--- consume current user context
const otherUsers = useOtherUsers(); <--- consume other users context
// Get the most updated data from the users context
const updatedUserData = (() => {
const updatedUserData =
userData.id === currentUser.data.id
? currentUser.data
: otherUsers.getUser(userData.id);
return {
...userData,
...(updatedUserData && updatedUserData),
};
})();
return updatedUserData;
}
Any ideas?