搜尋

首頁  >  問答  >  主體

React/Next 更新狀態並在 useEffect 之後重置它

我正在嘗試從api 串流傳輸數據,但是在渲染期間,useEffect 被多次調用,其中在初始頁面加載期間,除了被多次調用之外,一切都工作正常,但是當我刷新時在瀏覽器中的頁面上,也會發生同樣的情況,但teamData 在載入後也會設定為null。

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

狀態僅在程式碼的其餘部分中引用,但在此程式碼段之後從未實際再次設定。我如何讓 React/Next 停止將 teamData 重置為 null,作為獎勵,我如何讓它只調用 useEffect 一次?

P粉908643611P粉908643611445 天前520

全部回覆(2)我來回復

  • P粉032649413

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

    useEffect 將 id 作為依賴項,因此我猜測 id 的值會更改多次,導致該元件重新渲染。不過,我建議您分享更多信息,因為此程式碼片段沒有顯示很多內容。

    為什麼不使用伺服器端道具?請參閱下面的範例。

    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
    }

    回覆
    0
  • P粉773659687

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

    您的效果多次觸發有兩個原因。

    1. Next.js 頁面路由器查詢參數在初始渲染期間未定義- https://nextjs.org/docs/pages/api-reference/functions/use-router#router-object

    2. 使用嚴格模式時,React 18 在開發模式下卸載並重新安裝元件- https://react.dev/blog/2022/03/08/react-18-upgrade-guide# updates-to-strict-mode< /p>

    請查看以以下方式重寫您的效果是否可以解決您的問題。

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

    回覆
    0
  • 取消回覆