我正在尝试从映射的对象列表中找到链接到详细信息页面的最佳方法。该列表可从API获取项目,并且工作正常。问题是我无法将ID传递到我的详细信息页面,并且在单击对象时遇到此错误。
:3000 / _next / static / development / pages / _app.js?ts = 1592696161086:1299 GET http:// localhost:3000 / flowers / [object%20Object] 404(未找到)
以及网址http://localhost:3000/flowers/[object%20Object]
这就是我的/pages/flowers.js中的内容
import React, { useState, useEffect } from 'react'
import Head from 'next/head'
import Layout from '../components/layout'
import Link from 'next/link'
import utilStyles from '../styles/utils.module.css'
export default function Flowers() {
const LISTURL = 'https://flowers-mock-data.firebaseio.com/flowers.json'
const TESTURL = 'https://flowers-mock-data.firebaseio.com/flowers/9.json'
const [items, setItems] = useState([])
useEffect(() => {
fetch(LISTURL)
.then((res) => res.json())
.then((json) => setItems(json))
}, [] )
return (
<Layout>
<Head>
<title>?</title>
</Head>
<section className={utilStyles.centerSection}>
<button>Shade loving plants</button>
<button>Sun loving plants</button>
</section>
{items.map((item) => (
<ul key={item._id.oid}>
<li className={utilStyles.listItem}>
<Link href='/flowers/[flowerid]' as={`/flowers/${item._id}`}>
<a className={utilStyles.list}>
<h2 className={utilStyles.headingTop}>{item.common_name}</h2>
<img className={utilStyles.imgList} src={`${item.cover_image}`} alt={item.common_name} />
</a>
</Link>
</li>
</ul>
))
}
</Layout>
)
}
这是pages / [flowerid] .js
import React, { useEffect, useState } from 'react'
import Head from 'next/head'
import Router from 'next/router'
import axios from 'axios'
import Layout from '../components/layout'
import utilStyles from '../styles/utils.module.css'
const FlowerDetail = () => {
const [flower, setFlower] = useState(null)
useEffect(() => {
const fetchData = async () => {
const { flowerId } = Router.query
try {
const { data } = await axios.get(
`https://flowers-mock-data.firebaseio.com/flowers/${flowerId}.json`
)
console.log(`blomma`, data)
setFlower(data)
} catch (error) {
console.log(`Can not find id`, error)
}
}
fetchData()
}, [])
if (!flower) return <div>Loading...</div>
console.log('no flowers to see')
return (
<Layout>
<Head>
<title>?</title>
</Head>
<div>
<p>Blooming season {flower.blooming_season}</p>
<img className={utilStyles.imgList} src={`${flower.cover_image}`} alt={flower.common_name} />
<p>Common name {flower.common_name}</p>
<h5>{flower.notes}</h5>
</div>
</Layout>
)
}
export default FlowerDetail;
答案 0 :(得分:0)
来自您的API的_id
是一个包含oid
属性的对象:
"_id": {
"oid": "5e57880c9fa50a095f475c18"
},
因此,您需要将items._id.oid
属性用作链接源。照原样,您正在将id
对象传递到链接源,这就是为什么您的链接无效的原因:http://localhost:3000/flowers/[object%20Object]
不幸的是,这不是唯一的问题。另一个问题是当前数据结构不包含对URL参数id的任何引用(其中1.json
应该引用oid: 5e579cdfe99bdd0ca1cf64a3
,2.json
引用oid: 5e579dfcb664120cd14b4331
和等等),因此您需要重新配置API数据,以在每个数据文档(id
,id: 1
,...等)中包含具有此URL id: 2
的属性,然后将id
用作链接源,否则,您将不得不重新配置API以将此oid
属性用作要匹配的URL参数(而不是1.json
,它将使用{ {1}}作为要与之匹配并成为oid
的URL参数。
例如,此API endpoint(来自http://jsonplaceholder.typicode.com)包含一个5e579cdfe99bdd0ca1cf64a3.json
属性,该属性用作URL参数以通过其id
来检索特定的JSON文件。 (请注意, URL 和 JSON数据都包含id
中的id
)。
请注意,如果您使用的是Chrome,则可以安装extension来美化/格式化9
,使其看起来像this。
作为参考,这是查询此endpoint时当前响应的结构(请注意,JSON
中的9
并未在JSON数据内的任何地方被引用/使用,因此使用https://flowers-mock-data.firebaseio.com/flowers/9.json
(oid
)作为参数无效:
https://flowers-mock-data.firebaseio.com/flowers/5e57a0e1e5f2470d789335c2.json
我整理了一个带有一些注释的示例,该注释包含了以上段落中提到的API端点(jsonplaceholder),并实现了nextjs的data fetching方法(为简单起见,排除了{
"__v": {
"numberInt": "0"
},
"_id": {
"oid": "5e57a0e1e5f2470d789335c2"
},
"blooming_season": "Late Spring",
"common_name": "Ornamental onion",
"cover_image": "https://images.unsplash.com/photo-1565685225009-fc85d9109c80?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80",
"depth": {
"numberInt": "3"
},
"height": [
{
"numberInt": "6"
},
{
"numberInt": "60"
}
],
"latin_name": "Allium",
"notes": "Usually pest-free; a great cut flower",
"soil": [
"well drained",
"moist",
"fertile"
],
"spacing": {
"numberInt": "12"
},
"sun": true
}
;但是,从技术上讲,它可以替换动态pages/users/[id].js页中的getStaticPaths
,因为在运行时永远不会更改/更新数据。