[英]Nextjs dynamic routes issue - dynamic routes not displaying proper content
我在user
文件夾中有這個[id].js
動態路由。 我使用getStaticPaths
來靜態預渲染這些路徑,然后使用getStaticProps
獲取每個頁面的數據。
但是,在生產中(由於這些功能在開發模式下對每個請求運行,因此問題不存在),例如在/user/a
到/user/b
之間導航時,它會一直顯示/user/a
數據。
我也在使用react-query
。 我知道我可以通過在路由更改時刷新客戶端上的數據來解決這個問題,但現在我問:這不應該是使用getStaticPaths
和getStaticProps
創建動態路由時的默認/預期行為嗎?
所有動態路由都會發生這種情況,這里是user
:
import React from "react";
import Image from "next/image";
import { dehydrate, QueryClient } from "react-query";
import { Layout, Posts } from "../../components";
import {
postsByUserQuery,
userQuery,
usersQuery,
postsSavedByUserQuery,
} from "../../utils/data";
import {
fetchPostsByUser,
fetchUser,
fetchPostsSavedByUser,
} from "../../utils/fetchers";
import { useData } from "../../hooks/useData";
import { client } from "../../client/client";
import { useRouter } from "next/router";
import { useSession, signOut } from "next-auth/react";
const UserProfile = () => {
const router = useRouter();
const { id } = router.query;
const { data: session } = useSession();
const { data: user } = useData("userInfo", fetchUser, id);
const {
data: postsByUser,
isFetching: isFetchingPostsByUser,
refetch: refetchPostsByUser,
} = useData("postsByUser", fetchPostsByUser, id);
const {
data: postsSavedByUser,
isFetching: isFetchingPostsSavedByUser,
refetch: refetchPostsSavedByUser,
} = useData("postsSavedByUser", fetchPostsSavedByUser, id);
return (
<Layout
title={`PostIt | ${user[0]?.userName} Profile`}
ogUrl={process.env.NEXT_PUBLIC_BASEURL + router.asPath}
ogType="article"
>
<div className="relative w-full h-[250px] 2xl:h-[350px]">
<Image
layout="fill"
placeholder="blur"
blurDataURL={`https://source.unsplash.com/1600x900/?${postsByUser[0]?.category}`}
src={`https://source.unsplash.com/1600x900/?${postsByUser[0]?.category}`}
alt="user-Cover-Pic"
objectFit="cover"
priority
/>
</div>
<section className="flex flex-col w-full gap-5 px-4 py-12 mx-auto max-w-7xl md:px-8 lg:px-10">
<div className="flex flex-col justify-center items-center gap-8">
<h1 className="text-center text-2xl 2xl:text-4xl text-white font-bold">
{user[0]?.userName}
</h1>
<div className="ring-2 ring-gray-100 p-1 flex items-center justify-center rounded-full w-60 h-60 2xl:w-80 2xl:h-80">
<div className="relative w-full h-full">
<Image
src={user[0]?.image}
layout="fill"
className="rounded-full"
alt="User Avatar"
objectFit="cover"
/>
</div>
</div>
{user[0]?._id === session?.user?.uid && (
<div className="w-full flex items-center justify-center">
<button
type="button"
className="mt-2 w-full max-w-[120px] rounded-lg text-base 2xl:text-lg text-white font-bold border-none outline-none bg-red-500 p-2 flex items-center justify-center transition duration-150 hover:bg-red-700"
onClick={() => signOut({ callbackUrl: "/login" })}
>
Logout
</button>
</div>
)}
<div className="flex flex-col gap-2 mt-5 w-full">
<span className="text-white text-base 2xl:text-xl font-bold">
Posts by {user[0]?.userName}{" "}
{postsByUser?.length > 0 ? `(${postsByUser.length})` : `(0)`}
</span>
{postsByUser?.length > 0 ? (
<Posts
posts={postsByUser}
refresh={refetchPostsByUser}
isFetching={isFetchingPostsByUser}
/>
) : (
<p className="text-sm 2xl:text-lg text-gray-400 w-full">
This user has not posted anything yet.
</p>
)}
</div>
<div className="flex flex-col gap-2 mt-5 w-full">
<span className="text-white text-base 2xl:text-xl font-bold">
Saved by {user[0]?.userName}{" "}
{postsSavedByUser?.length > 0
? `(${postsSavedByUser.length})`
: `(0)`}
</span>
{postsSavedByUser?.length > 0 ? (
<Posts
posts={postsSavedByUser}
refresh={refetchPostsSavedByUser}
isFetching={isFetchingPostsSavedByUser}
/>
) : (
<p className="text-sm 2xl:text-lg text-gray-400 w-full">
This user has not saved any post yet.
</p>
)}
</div>
</div>
</section>
</Layout>
);
};
export async function getStaticPaths() {
const query = usersQuery();
const users = await client.fetch(query);
const paths = users.map((user) => ({
params: { id: user._id },
}));
return {
paths,
fallback: false,
};
}
export async function getStaticProps({ params }) {
const queryClient = new QueryClient();
const user = userQuery(params.id);
const postsByUser = postsByUserQuery(params.id);
const postsSavedByUser = postsSavedByUserQuery(params.id);
await queryClient.prefetchQuery("userInfo", () =>
client.fetch(user).then((data) => data)
);
await queryClient.prefetchQuery("postsByUser", () =>
client.fetch(postsByUser).then((data) => data)
);
await queryClient.prefetchQuery("postsSavedByUser", () =>
client.fetch(postsSavedByUser).then((data) => data)
);
return {
props: {
dehydratedState: dehydrate(queryClient),
},
revalidate: 30,
};
}
export default UserProfile;
編輯: useData
自定義鈎子:
import { useQuery } from "react-query";
import { toast } from "react-toastify";
export const useData = (queryKey, queryFn, queryFnParam1, queryFnParam2) => {
const { data, isFetching, refetch } = useQuery(
queryKey,
() => queryFn(queryFnParam1, queryFnParam2),
{
staleTime: 2.5 * 60 * 1000, //2.5 minutes
onError: (error) => {
toast.error(
`Couldn't establish connection due to error: ${error.message}`
);
},
}
);
return { data, isFetching, refetch };
};
您需要在 queryKey 中包含 userId。 否則,所有請求都寫入同一個緩存條目。 React Query Devtools 應該會向您展示這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.