NextJS+Sanity商品页面报错:Cannot read properties of null (reading 'name')
问题解决:Error: Cannot read properties of null (reading 'name')
核心问题是getProduct返回了null,导致直接访问product.name时报错,根源集中在以下几点:
1. GROQ查询的文档类型写错
你的电商项目中,产品对应的Sanity文档类型应该是product,但代码里写的是_type == "project"——这会导致查询不到任何产品数据,直接返回null。修改GROQ查询里的类型:
// sanity\sanity-utils.ts 中的GROQ语句修改 groq`*[_type == "product" && slug.current == $slug][0]{ _id, createdAt, name, "slug": slug.current, brand, "image": image[].asset->url, pack, sku, sizes, description, "category": category->name, "subcategory": subcategory->name }`
2. 参数传递方式错误
你给fetch传的"{slug}"是错误写法,Sanity的fetch方法第二个参数需要传递变量对象,用来绑定GROQ里的$slug变量,同时避免字符串拼接带来的安全风险。修改后的getProduct函数:
// sanity\sanity-utils.ts 完整修改 export async function getProduct(slug: string): Promise<Product | null> { return createClient(clientConfig).fetch( groq`*[_type == "product" && slug.current == $slug][0]{ _id, createdAt, name, "slug": slug.current, brand, "image": image[].asset->url, pack, sku, sizes, description, "category": category->name, "subcategory": subcategory->name }`, { slug } // 直接传递变量对象,无需引号 ) }
注意:把返回类型改为Promise<Product | null>,因为确实存在查询不到数据的情况,类型定义更严谨。
3. 处理产品不存在的边界情况
在页面组件中,必须先判断product是否存在,再访问其属性,避免报错:
// app\product[productId]\page.tsx 修改后 import { getProduct } from "@/sanity/sanity-utils"; type Props = { params: { product: string } } export default async function Product({ params }: Props) { const slug = params.product; const product = await getProduct(slug); if (!product) { return <div>产品不存在</div>; } return <div>{product.name}</div>; }
补充:关于$slug=undefined错误的说明
之前你去掉引号传{slug}报错,是因为当时GROQ用的是字符串拼接"${slug}",而非变量绑定$slug,Sanity识别不到$slug变量才会提示undefined。现在改用变量绑定的方式,这个问题就会消失。
内容的提问来源于stack exchange,提问作者Efrain
相关产品推荐
相关产品推荐

