与Next.js动态链接或路由

时间:2020-06-21 00:17:59

标签: reactjs dynamic next.js

我正在尝试从映射的对象列表中找到链接到详细信息页面的最佳方法。该列表可从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;

1 个答案:

答案 0 :(得分:0)

阻碍你前进的问题...

来自您的API_id是一个包含oid属性的对象:

 "_id": {
   "oid": "5e57880c9fa50a095f475c18"
 },

因此,您需要将items._id.oid属性用作链接源。照原样,您正在将id 对象传递到链接源,这就是为什么您的链接无效的原因:http://localhost:3000/flowers/[object%20Object]

不幸的是,这不是唯一的问题。另一个问题是当前数据结构不包含对URL参数id的任何引用(其中1.json应该引用oid: 5e579cdfe99bdd0ca1cf64a32.json引用oid: 5e579dfcb664120cd14b4331和等等),因此您需要重新配置API数据,以在每个数据文档(idid: 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


OID与请求的API端点不匹配

作为参考,这是查询此endpoint时当前响应的结构(请注意,JSON中的9并未在JSON数据内的任何地方被引用/使用,因此使用https://flowers-mock-data.firebaseio.com/flowers/9.jsonoid)作为参数无效:

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,因为在运行时永远不会更改/更新数据。

fetch data example repo