首页 > 解决方案 > 防止组件自定义钩子无限重新渲染

问题描述

我从我的顶级页面/组件调用下面的自定义数据获取钩子。

export const Teams: FC = (): JSX.Element => {
  const { teamList, isLoading } = useTeamList();

  return (
    <Child
      teams={teamList}
      moreTeams={teamList}
    />
  );
};

我的自定义钩子看起来像这样:

export const useTeamList = () => {
  const [teamList, setTeamList] = useState<any[]>([]);
  const [isLoading, setLoading] = useState(true);

    setTimeout(() => {
      setTeamList(
        makeSequence((Math.random() * (3 - 0 + 1)) << 0).map(() => ({
          title: faker.lorem.words(3),
          description: faker.lorem.words(3),
          datetime: dayjs(),
        })),
      );
      setLoading(false);
    }, 1000);

  return {
    teamList,
    isLoading,
  };
};

不幸的是,这个钩子似乎被无限调用。我该如何阻止这种情况发生?我认为数据的每次更新都会导致它重新渲染,从而再次获取数据。我通常会使用 useEffect 来获取数据,但在这种情况下,我必须使用自定义挂钩。

标签: reactjstypescriptreact-hooks

解决方案


你需要在你的钩子里使用 useEffect ,并清理副作用

export const useTeamList = () => {
  const [teamList, setTeamList] = useState<any[]>([]);
  const [isLoading, setLoading] = useState(true);

  React.useEffect(() => {
     const timeOut = setTimeout(() => {
      setActivityList(
        makeSequence((Math.random() * (3 - 0 + 1)) << 0).map(() => ({
          title: faker.lorem.words(3),
          description: faker.lorem.words(3),
          datetime: dayjs(),
        })),
      );
      setLoading(false);
    }, 1000);
    return () => { clearTimeout(timeOut) }
  }, [])
    

  return {
    teamList,
    isLoading,
  };
};

推荐阅读