nextjs-TypeError:无法读取未定义的属性(读取‘title’)
我正在使用 nextjs 作为框架,尝试使用 slug 显示标题
我在 [slug].js 文件中的代码是:
import React, { useState } from 'react'
import { useRouter } from 'next/router'
const slug = ({proDetail}) => {
const router = useRouter();
const { slug } = router.query
console.log(proDetail[slug].title)
return (<div>title:{proDetail[slug].title}</div>)
}
export default slug
在上面的代码(第 3 行)中,proDetails 是 _app.js 中的一个对象,它作为 [slug].js 的 prop 给出
export default function App({ Component, pageProps }) {
var proDetail = {
s1: { title: "Tomato", disc:"lorem" },
s2: { title: "Pepper", disc:"lorem" },
s3: { title: "Lettuce", disc:"lorem" },
s4: { title: "Carrot", disc:"lorem" },
s5: { title: "Radish", disc:"lorem" }
}
return <>
<Component proDetail={proDetail} {...pageProps}/>
</>
}
我希望我的标题能够在对象中为不同的 url http://localhost:3000/s{i} 显示相应的标题(其中“i”是从 1 到 5 的数字,因为我的 proDetail 中只有 s1 到 s5 的键对象)
我的动机是如果我更改 URL 但出现 TypeError: 无法读取未定义的属性(读取“title”) 如果我使用 proDetail["s2"].title 代替 proDetail[slug].title 那么我的标题就会显示在网页上,但这只显示 key:s2 的标题
import React, { useState } from 'react'
import { useRouter } from 'next/router'
const slug = ({proDetail}) => {
const router = useRouter();
const { slug } = router.query
return (<div>title:{proDetail["s2"].title}</div>)
}
但显示 title: Pepper 甚至会出现在 http://localhost:3000/s(anyValue) 中,因为我已经更改了我的 HTML。
如何解决此 TypeError:无法读取未定义的属性(读取“title”)。我不想为每个标题创建单独的页面,而是想使用 slug。
我理解控制台语句和 html 在获取定义的 slug 值之前被渲染,但如何克服这个错误
import React from 'react'
import { useRouter } from 'next/router'
const slug =(({proDetail}) => {
const router = useRouter();
let {slug} =router.query
console.log(slug)
return (<div>title:
{slug === undefined ? 'Loading...' : JSON.stringify(proDetail[slug].title)}
</div>)
})
export default slug
我明白,只有当我的 slug 未定义时,我才能评估 proDetail[slug].title
您使用
useEffect
的方式几乎是正确的,但是您需要验证
slug
值是否为空。
useEffect(() => {
if(slug) {
console.log(proDetail[slug].title);
}
}, [slug])
原因是当
slug
不可用时,
useEffect
也会在第一次渲染时触发。因此,您得到了同样的错误。
您还可以使用在
next/router
包中定义的
router.isReady
,如下所示
import React, { useState, useEffect } from 'react'
import { useRouter } from 'next/router'
const Slug = ({proDetail}) => {
const [slugValue, setSlugValue] = useState();
const router = useRouter();
const { slug } = router.query;
useEffect(() => {
if(router.isReady) {
setSlugValue(slug);
}
}, [router.isReady]);
if(!slugValue) {
return null;
}
return (<div>title:{proDetail[slugValue]?.title}</div>)
}
export default Slug
此逻辑可以帮助您克服在某些情况下仍然允许空的
slug
的问题。
请注意,我将您的组件名称从
slug
更改为
Slug
,以避免您在组件中也使用的变量重复。