React/Next update state and reset it after useEffect
P粉908643611
P粉908643611 2023-09-11 12:41:54
0
2
512

I'm trying to stream data from the api, but during the render, useEffect is called multiple times, where during the initial page load, everything is working fine except being called multiple times, but when I refresh On the page in the browser, the same thing happens, but teamData is also set to null after loading.

const router = useRouter();
    const { id } = router.query;

    const [teamData, setTeamData] = useState(null);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        GetTeamData(id).then((value) => {
            setTeamData(value);
            setLoading(false);
            console.log("Got Value")
        })
    }, [id])

The status is only referenced in the rest of the code, but is never actually set again after this snippet. How do I make React/Next stop resetting teamData to null, and as a bonus, how do I make it only call useEffect once?

P粉908643611
P粉908643611

reply all(2)
P粉032649413

useEffect has id as a dependency, so I'm guessing that the value of id changes multiple times, causing the component to re-render. However, I recommend you share more information as this snippet doesn't show much.

Why not use server side props? See example below.

import type { InferGetServerSidePropsType, GetServerSideProps } from 'next'
 
type Repo = {
  name: string
  stargazers_count: number
}
 
export const getServerSideProps: GetServerSideProps<{
  repo: Repo
}> = async () => {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const repo = await res.json()
  return { props: { repo } }
}
 
export default function Page({
  repo,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
  return repo.stargazers_count
}
P粉773659687

There are two reasons why your effect triggers multiple times.

  1. Next.js page router query parameters are undefined during initial render - https://nextjs.org/docs/pages/api-reference/functions/use-router#router-object

  2. React 18 Uninstall and reinstall components in development mode when using strict mode - https://react.dev/blog/2022/03/08/react-18-upgrade-guide# updates-to-strict-mode

Please see if rewriting your effect as follows resolves your issue.

useEffect(() => {
  let shouldCancel = false;

  if (id !== undefined) {
    GetTeamData(id).then((value) => {
      if (!shouldCancel) {
        setTeamData(value);
        setLoading(false);
        console.log("Got Value");
      }
    });
  }

  return () => {
    shouldCancel = true;
  };
}, [id]);
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template