【问题标题】:Linking or Routing dynamicaly with Next.js使用 Next.js 动态链接或路由
【发布时间】:2020-10-11 01:24:07
【问题描述】:

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

【问题讨论】:

    标签: reactjs dynamic next.js


    【解决方案1】:

    阻碍你前进的问题...

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

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

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

    不幸的是,这不是唯一的问题。另一个问题是当前数据结构不包含对 URL 参数 id 的任何引用(其中 1.json 应该引用 oid: 5e579cdfe99bdd0ca1cf64a32.json 引用 oid: 5e579dfcb664120cd14b4331,等等),所以你会需要重新配置您的 API 数据以在每个数据文档(id: 1id: 2、...等)中包含带有此 URL id 的属性,然后使用该 id 作为链接源,否则您将拥有重新配置您的 API 以将此 oid 属性用作要匹配的 URL 参数(而不是 1.json,它将使用 oid 作为 URL 参数来匹配并成为 5e579cdfe99bdd0ca1cf64a3.json)。

    例如,此API endpoint(来自http://jsonplaceholder.typicode.com)包含一个id 属性,该属性用作URL 参数以通过其id 检索特定的JSON 文件(注意both URLJSON 数据 包含 id9)。

    附带说明,如果您使用的是 Chrome,则可以安装此 extension 以美化/格式化 JSON,使其看起来像 this


    OID 与请求的 API 端点不匹配

    作为参考,当您查询此 endpoint 时,您的响应的当前结构如下(请注意,https://flowers-mock-data.firebaseio.com/flowers/9.json 中的 9 未在 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
    } 
    

    获取数据仓库示例

    我已经用一些 cmets 组合了一个示例,其中包含上一段中提到的 API 端点(jsonplaceholder),并实现了一些 nextjs 的 data fetching 方法(为简单起见,排除了 getStaticPaths;但是,从技术上讲,它可以替换动态pages/users/[id].js 页面中的getServerSideProps,因为数据在运行时永远不会更改/更新):

    fetch data example repo

    【讨论】:

      猜你喜欢
      • 2023-03-23
      • 2022-01-10
      • 2021-11-18
      • 2022-11-05
      • 2018-05-11
      • 2021-02-18
      • 2020-09-08
      • 2022-01-04
      • 2021-12-17
      相关资源
      最近更新 更多