You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中用getStaticPaths/Props结合React Context遇ISR错误求助

Next.js ISR 产品详情页实现错误修复

我用Next.js、TypeScript和Firebase开发简易落地页,把Firestore的产品数据存在React Context里,尝试用ISR实现localhost:3000/product/[slug].tsx产品详情页时出现错误,相关代码如下:

interface Props {
    slug:Products
}

const ProductPage: NextPage<Props> = ({ slug }) => {
    const { products } = useContext(DbContext)
    const product = products.filter(product => product.slug === `${slug}`)
    

    return (
        <MainLayout title={``} pageDescription={''} imageFullUrl={''}>
           // product tsx
        </MainLayout>
    )
}


export const getStaticPaths: GetStaticPaths = async (ctx) => {

    const { products } = useContext(DbContext)
     const slugs = products.map(product => product.slug)
    return {
        paths: slugs.map((slug) => ({
            params: { slug }
          })),
        fallback: "blocking"
    }
}




export const getStaticProps: GetStaticProps = async ({ params }) => {
    const { slug } = params as { slug: string }  

    if (!slug) {
        return {
            redirect: {
                destination: "/",
                permanent: false
            }
        }
    }  
    return {
        props: {
            slug
        },
        revalidate:86400
    }
}


export default ProductPage

错误截图:
错误截图

问题根源

  1. getStaticPaths中调用useContext:React Hooks仅能在React组件或自定义Hooks中使用,getStaticPaths是Next.js的静态生成函数,运行在非组件环境,无法访问React Context,这是直接触发报错的原因。
  2. Props类型不匹配:Props将slug定义为Products类型,但实际传递的是字符串,导致类型冲突。
  3. 依赖Context过滤产品:ISR场景下,应在服务端直接获取对应slug的产品数据,而非依赖客户端Context,否则易出现数据不一致或加载延迟问题。

修正后的代码

1. 修正getStaticPaths:直接从Firestore获取slug

import { db } from '../path/to/your/firebase/config'; // 导入你的Firebase配置文件
import { collection, getDocs } from 'firebase/firestore';

// ...其他组件代码

export const getStaticPaths: GetStaticPaths = async () => {
  // 直接连接Firestore获取所有产品的slug
  const productsCol = collection(db, 'products');
  const productsSnapshot = await getDocs(productsCol);
  const slugs = productsSnapshot.docs.map(doc => doc.data().slug);

  return {
    paths: slugs.map(slug => ({ params: { slug } })),
    fallback: "blocking"
  }
}

2. 修正getStaticProps:直接获取对应产品数据

import { query, where, getDocs } from 'firebase/firestore';

export const getStaticProps: GetStaticProps = async ({ params }) => {
  const { slug } = params as { slug: string };

  if (!slug) {
    return { redirect: { destination: "/", permanent: false } };
  }

  // 查询对应slug的产品
  const productsCol = collection(db, 'products');
  const productQuery = query(productsCol, where('slug', '==', slug));
  const productSnapshot = await getDocs(productQuery);

  // 未找到产品则返回404
  if (productSnapshot.empty) {
    return { notFound: true };
  }

  const product = productSnapshot.docs[0].data() as Products;

  return {
    props: { product },
    revalidate: 86400 // 24小时自动重新验证数据
  }
}

3. 修正组件与Props定义

interface Props {
  product: Products; // 直接接收完整产品数据
}

const ProductPage: NextPage<Props> = ({ product }) => {
  // 直接使用传入的product,无需从Context过滤
  return (
    <MainLayout 
      title={product.name} 
      pageDescription={product.description} 
      imageFullUrl={product.imageUrl}
    >
      {/* 渲染产品内容 */}
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      {/* 其他产品信息渲染 */}
    </MainLayout>
  )
}

关键注意事项

  • 静态生成/ISR相关函数(getStaticPaths/getStaticProps)不能调用React Hooks,必须直接从数据源获取数据。
  • ISR模式下,优先在服务端获取当前页面的精准数据,减少客户端依赖,既提升加载速度又保证数据一致性。
  • TypeScript类型定义需与实际数据匹配,避免类型不匹配引发的错误。

内容的提问来源于stack exchange,提问作者guido

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 19:15:35