首页 > 解决方案 > 我的 React Child 正在使用钩子,并且由于某种原因,正在重新渲染父级

问题描述

问题

如果我的孩子使用一个消耗上下文的钩子,为什么我的父组件会被重新渲染?

代码

我在 GitHub 上读到,为了防止使用消耗上下文的钩子重新渲染组件,执行以下操作是一个不错的选择:

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;
}

如您所见,在我的 MemoizedUserPosts 中,我只使用了两个钩子,它不会重新渲染组件。

当我将数据传递给 CardList 时,我正在渲染卡片。此 Card 组件呈现我的 AuthorRow 组件,这导致重新呈现“MemoizedUserPosts”,因为使用了一个消耗我的用户上下文的钩子:

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}
    />
  );
}

如果我删除该行,那么当我的上下文中的 userData 发生更改时,不会重新渲染 MemoizedUserPosts。

这是我的 useUpdatedUserData 钩子:

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;
}

有任何想法吗?

标签: javascriptreactjsreact-nativereact-hooks

解决方案


推荐阅读