Я пытаюсь найти лучший способ ссылки на страницу сведений из списка сопоставленных объектов. Список извлекает элементы из API и работает нормально. Проблема в том, что я не могу передать идентификатор на свою страницу сведений и получаю эту ошибку, когда нажимаю на объекты.
: 3000 / _next / static / development / pages / _app.js? Ts = 1592696161086: 1299 GET http: // localhost: 3000 / flowers / [object% 20Object] 404 (не найдено)
И в URL 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>
)
}
Это страницы / [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;
1 ответ
Проблемы, сдерживающие вас ...
_id
, исходящий из вашего API, представляет собой объект, который содержит Свойство oid
:
"_id": {
"oid": "5e57880c9fa50a095f475c18"
},
Поэтому вы захотите использовать свойство items._id.oid
в качестве источника ссылки. Таким образом, вы передаете id
объект источнику ссылки, поэтому ваши ссылки недействительны : http://localhost:3000/flowers/[object%20Object]
К сожалению, это не единственная проблема. Другая проблема заключается в том, что текущая структура данных не содержит ссылки на идентификатор параметра URL (где 1.json
должен ссылаться на oid: 5e579cdfe99bdd0ca1cf64a3
, 2.json
ссылки oid: 5e579dfcb664120cd14b4331
и так далее), поэтому вам нужно будет перенастроить данные API, чтобы включить свойство с этим URL id
в каждый документ данных (id: 1
, id: 2
, ... и т. д.), а затем используйте этот id
в качестве источника ссылки ИЛИ вам придется перенастроить свой API, чтобы использовать это свойство oid
в качестве параметра URL для сопоставления (вместо 1.json
он будет использовать { {X10}} в качестве параметра URL для сопоставления и равного 5e579cdfe99bdd0ca1cf64a3.json
).
Например, эта конечная точка API (которая поступает из http://jsonplaceholder.typicode.com) содержит свойство id
, которое используется в качестве параметра URL для получения определенного файла JSON по его { {X1}} (обратите внимание, как и URL , и данные JSON содержат id
из 9
).
Кстати, если вы используете Chrome, вы можете установить это расширение < / a>, чтобы изменить / форматировать JSON
, чтобы он выглядел как this.
OID не соответствует запрошенной конечной точке API
Для справки, вот как в настоящее время структурирован ваш ответ, когда вы запрашиваете эту конечную точку (обратите внимание, что 9
в https://flowers-mock-data.firebaseio.com/flowers/9.json
нигде не упоминается / не используется в данных JSON, поэтому использование oid
(https://flowers-mock-data.firebaseio.com/flowers/5e57a0e1e5f2470d789335c2.json
) в качестве параметра не будет действительный):
{
"__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
}
Пример репозитория выборки данных
Я собрал пример с некоторыми комментариями, который включает конечную точку API (jsonplaceholder), упомянутую в абзаце выше, а также реализует некоторые из nextjs методы выборки данных (исключен getStaticPaths
для простоты; однако технически он может заменить getServerSideProps
в динамическом pages / users / [id]. js, поскольку данные никогда не будут изменены / обновлены во время выполнения):
получить репозиторий примера данных
Похожие вопросы
Новые вопросы
reactjs
React — это библиотека JavaScript для создания пользовательских интерфейсов. Он использует декларативную парадигму на основе компонентов и стремится быть эффективным и гибким.