ambe5960
ambe5960

Reputation: 1990

Prevent infinite rerender of component custom hook

I call a custom data fetching hook below from my top-level page/component.

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

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

and my custom hook looks like this:

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

Unfortunately this hook is called seemingly infinitely. How do I stop this from happening? I think each update of the data is causing it to re-render, and thus fetch the data again. I would normally use a useEffect to fetch the data, but in this case I have to use a custom hook.

Upvotes: 3

Views: 738

Answers (1)

iunfixit
iunfixit

Reputation: 994

You need to use useEffect inside your hook, and cleanup the side effects

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

Upvotes: 4

Related Questions