Next.js 13.0.5中getStaticProps跳转返回undefined,刷新才正常
我在Next.js 13.0.5项目里遇到个问题:网站内部跳转(比如用next/link跳转到/product/[slug]页面)时,product、seller都是undefined,只有刷新页面后数据才正常显示。我试过用useEffect在客户端拉数据,但必须要服务端渲染的逻辑生效才行。这套逻辑在其他项目里能正常跑,实在找不到问题出在哪,求帮忙!
项目路径:/product/[slug].tsx,相关代码如下:
const ProductPage = ({ product, seller, }: { product: Product; seller: Seller; }) => { const { user, updateUser } = useUser(); console.log(seller, product); if (!product || !seller) { return ( <PageLayout> <p className="animate-pulse">Cargando...</p> </PageLayout> ); } return ( <PageLayout> <div className="contain flex flex-col"> <ProductBody product={product} seller={seller} isActive={user.id === seller.id} /> </div> </PageLayout> ); }; export const getStaticPaths: GetStaticPaths = async () => { //logic here return { paths: allPaths, fallback: false }; }; export const getStaticProps: GetStaticProps = async ({ params }) => { const productId = params?.slug; if (!productId) { return { props: { product: null, user: null } }; } const { data: product, error } = await supabase .from("products") .select("seller, id, published_version, created_at, published") .eq("id", productId) .eq("published", true) .single(); console.log("RESULTADOS", product, error); if (error || !product) { return { props: { product: null } }; } if (!product || !product.seller) { return { notFound: true }; // Return notFound: true when the product doesn't exist } const { data: seller, error: sellerError } = await supabase .from("users") .select("*") .eq("id", product.seller) .single(); if (sellerError || !seller) { return { notFound: true }; } return { props: { product, seller, }, revalidate: 1, }; }; export default ProductPage;
可能的原因及解决办法
1. Pages Router与App Router混淆
你用的是Pages Router的getStaticProps/getStaticPaths规则,如果项目是App Router结构(页面放在app/目录下),这些函数不会生效。先确认页面是在pages/目录下,而非app/目录。
2. getStaticPaths配置问题
如果fallback设为false,但跳转的slug不在预生成的allPaths列表里,内部跳转时会因为没有预渲染数据导致props为空。
- 检查
getStaticPaths里的allPaths是否正确包含了所有已发布商品的slug:export const getStaticPaths: GetStaticPaths = async () => { const { data: products } = await supabase.from("products").select("id").eq("published", true); const allPaths = products?.map(product => ({ params: { slug: product.id } })) || []; return { paths: allPaths, fallback: false }; }; - 若商品是动态新增的,建议把
fallback设为'blocking',未预生成的页面会在首次访问时由服务端实时生成:return { paths: allPaths, fallback: 'blocking' };
3. 路由跳转的预加载缓存问题
Next.js的Link组件默认会预加载页面,可能缓存了旧的空数据。可以临时禁用预加载测试:
<Link href={`/product/${slug}`} prefetch={false}>查看商品</Link>
4. Props类型与默认值问题
给组件props添加默认值,避免内部跳转时因props未传递导致undefined:
const ProductPage = ({ product = null, seller = null, }: { product: Product | null; seller: Seller | null; }) => { // ... };
5. Supabase查询权限或数据问题
确认服务端执行getStaticProps时,Supabase有足够权限读取products和users表数据;同时检查product.seller是否为有效的用户ID,避免查询不到卖家数据。可以在getStaticProps里增加更多日志,确认内部跳转时该函数是否被触发(内部跳转时getStaticProps仅在fallback场景下会服务端执行)。
内容的提问来源于stack exchange,提问作者Emiliano

