React Query 在 Next.js 中切换路由时重新获取数据

huangapple go评论121阅读模式
英文:

React Query refetching data when changing routes in nextjs

问题

I am using @tanstack/react-query": "^4.26.0" in my "next": "13.2.1", project. I have a query which triggers on the index page.

GiveawayDetailsQuery-

export const useGiveawayDetails = () => useQuery(["giveawayDetails"], async () => {
    const response = await axios.get("/api/giveaway/giveaway-details")
    const data: giveawayDetails = await response.data;
    console.log(data);
    return data;
},
    {
        refetchOnWindowFocus: false,
        refetchOnMount: false,
        refetchInterval: 5 * 60 * 1000,
        onError: (error: any) => {
            if (error.response.status === 422 || error.response.status === 401) {
                toast(error.response.data.data.detail, { type: "error", toastId: "unauthorized" });
            } else {
                toast(error.response.data.data.detail, { type: "error" });
            }
        }
    },
);

My index.tsx page -

export default function Home() {

  return (
    <>
      <main className={styles.main}>
        <Giveaway />
        <BrandDiscounts />
        <YourRewards />
      </main>
    </>
  )
}

My Giveaway.tsx component -

const Giveaway = () => {
    const { isLoading, isError, data, error } = useGiveawayDetails();
    return (
        <div className={styles.container}>
            <p className="text-600 text-md">Giveaways</p>
            <div className={styles["giveaway-container"]}>
                {
                    isLoading && !isError & & <Skeleton
                        variant="rectangular"
                        width={210}
                        height={118}
                        className={styles["loading-skeleton"]} />
                }
                {
                    isError && !isLoading & & <p className={`text-500 text-md ${styles["error-container"]}`}>{error?.response?.data?.data?.detail ?? "Something went wrong"}</p>
                }
                {
                    !isError && !isLoading & & data?.giveaway & &
                    <Link href="/giveaway">
                        <Image src={data.giveaway[0].thumbnail_url} alt={data.giveaway[0].title} width={887} height={1183} priority={true} />
                    </Link>
                }
            </div>
        </div>
    )
}

export default Giveaway

Now the thing is when I open the index page, the query is fetched, and when I move to some other routes, and go back to the index page the query is fetched again automatically, and I want to disable this.
I want to refetch the query when I want to.

英文:

I am using @tanstack/react-query": "^4.26.0" in my "next": "13.2.1", project. I have a query which triggers on the index page.

GiveawayDetailsQuery-

export const useGiveawayDetails = () => useQuery(["giveawayDetails"], async () => {
    const response = await axios.get("/api/giveaway/giveaway-details")
    const data: giveawayDetails = await response.data;
    console.log(data);
    return data;
},
    {
        refetchOnWindowFocus: false,
        refetchOnMount: false,
        refetchInterval: 5 * 60 * 1000,
        onError: (error: any) => {
            if (error.response.status === 422 || error.response.status === 401) {
                toast(error.response.data.data.detail, { type: "error", toastId: "unauthorized" });
            } else {
                toast(error.response.data.data.detail, { type: "error" });
            }
        }
    },
);

My index.tsx page -

export default function Home() {

  return (
    <>
      <main className={styles.main}>
        <Giveaway />
        <BrandDiscounts />
        <YourRewards />
      </main>
    </>
  )
}

My Giveaway.tsx component -

const Giveaway = () => {
    const { isLoading, isError, data, error } = useGiveawayDetails();
    return (
        <div className={styles.container}>
            <p className="text-600 text-md">Giveaways</p>
            <div className={styles["giveaway-container"]}>
                {
                    isLoading && !isError && <Skeleton
                        variant="rectangular"
                        width={210}
                        height={118}
                        className={styles["loading-skeleton"]} />
                }
                {
                    isError && !isLoading && <p className={`text-500 text-md ${styles["error-container"]}`}>{error?.response?.data?.data?.detail ?? "Something went wrong"}</p>
                }
                {
                    !isError && !isLoading && data?.giveaway &&
                    <Link href="/giveaway">
                        <Image src={data.giveaway[0].thumbnail_url} alt={data.giveaway[0].title} width={887} height={1183} priority={true} />
                    </Link>
                }
            </div>
        </div>
    )
}

export default Giveaway

Now the thing is when I open the index page, the query is fetched, and when I move to some other routes, and go back to the index page the query is fetched again automatically, and I want to disable this.
I want to refetch the query when I want to.

答案1

得分: 2

Create a new instance inside of your app, and on an instance ref (or in React state). This ensures that data is not shared between different users and requests, while still only creating the QueryClient once per component lifecycle.QueryClient.

const [queryClient] = React.useState(() => new QueryClient())

solved for me

英文:

From Tanstack Query => Create a new instance inside of your app, and on an instance ref (or in React state). This ensures that data is not shared between different users and requests, while still only creating the QueryClient once per component lifecycle.QueryClient

const [queryClient] = React.useState(() => new QueryClient())

solved for me

答案2

得分: 1

需要禁用查询并在需要手动触发查询时使用 refetch

英文:

You need to disable the query and use refetch when you want to manually trigger the query.

答案3

得分: 1

React Query在组件挂载时,当数据被视为陈旧时,将自动进行重新获取。查询的陈旧程度可以使用staleTime设置,其默认值为零。因此,您只需决定后端接收到的数据应被视为新鲜的时间,然后相应地设置staleTime。我在这个主题上有一篇完整的博客文章:https://tkdodo.eu/blog/react-query-as-a-state-manager

英文:

React Query will do automatic refetch when a component mounts AND the data is considered stale. Staleness of a query can be set with staleTime, and it defaults to zero. So really, all you have to decide is how long data you receive from the backend should be considered fresh and then set staleTime accordingly to your resource. I have a whole blogpost on that topic alone: https://tkdodo.eu/blog/react-query-as-a-state-manager

huangapple
  • 本文由 发表于 2023年3月8日 18:50:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75672073.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定