Next.js使用getStaticProps实现动态商品页报keys.join错误求助
问题原因
你遇到的TypeError: keys.join is not a function报错来自三处代码错误:
getStaticProps里调用ButterCMS接口的参数写法错误:你写的["products"] + id会被JS自动转成"productsid"字符串,而butter.content.retrieve第一个参数要求传入内容类型数组,传字符串进去后内部调用数组的join方法就会直接抛错。- 页面组件没有正确解构props,直接把入参当product数据使用,实际Next.js会把
getStaticProps返回的内容包在props对象里传入组件,不解构拿不到商品字段。 - 原代码里
const { data } = await res.data多写了一层await,res本身已经是await拿到的接口返回值,不需要再对res.data做await操作。
可直接运行的修复代码
直接替换pages/product/[id].js的全部内容即可:
import React from 'react' import Butter from "buttercms"; const Details = ({ product }) => { return ( <> <h1>{product.name}</h1> </> ) } export default Details export const getStaticPaths = async () => { const butter = Butter(process.env.REACT_APP_BUTTER_ECOMMERCE); const res = await butter.content.retrieve(["products"], { order: "name", }); const { data } = res.data; const products = data.products; const paths = products.map(product => { return { params: { id: product.id.toString() } } }) return { paths, fallback: false } } export async function getStaticProps(context) { const butter = Butter(process.env.REACT_APP_BUTTER_ECOMMERCE); const id = context.params.id; // 默认按slug匹配单条商品,如果你的id是自定义字段,把slug换成对应字段名,通过filter传参即可 const res = await butter.content.retrieve(["products"], { slug: id }); const { data } = res.data; const product = data.products[0]; return { props: { product, }, } }
补充说明
- 如果你的商品id不是ButterCMS默认生成的slug字段,而是自定义字段(比如自定义
goods_id),把getStaticProps里的接口参数改成filter: { 'goods_id': id }就能正确筛选到对应商品。 - Next.js中仅服务端使用的环境变量不需要加
REACT_APP_前缀,REACT_APP_是Create React App的环境变量规则,Next.js里只有需要暴露给浏览器端的变量才需要加NEXT_PUBLIC_前缀,你存的ButterCMS密钥属于服务端敏感信息,不要加暴露前缀避免泄露。 - React组件名建议保持首字母大写,避免触发不必要的编译警告。
内容的提问来源于stack exchange,提问作者Joesno
相关产品推荐
相关产品推荐

