search

Home  >  Q&A  >  body text

React/Next update state and reset it after useEffect

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粉908643611P粉908643611502 days ago548

reply all(2)I'll reply

  • P粉032649413

    P粉0326494132023-09-12 10:31:56

    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
    }

    reply
    0
  • P粉773659687

    P粉7736596872023-09-12 00:03:33

    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< /p>

    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]);
    

    reply
    0
  • Cancelreply