Связывание или маршрутизация динамически с Next. js - PullRequest
0 голосов
/ 21 июня 2020

Я пытаюсь найти лучший способ ссылки на страницу сведений из списка сопоставленных объектов. Список извлекает элементы из API и работает нормально. Проблема в том, что я не могу передать идентификатор на свою страницу сведений и получаю эту ошибку, когда нажимаю на объекты.

: 3000 / _next / static / development / pages / _app. js? ts = 1592696161086: 1299 GET http://localhost: 3000 / flowers / [object% 20Object] 404 (Not Found)

и в 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 Ответ

0 голосов
/ 21 июня 2020

Проблемы, сдерживающие вас ...

_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, ... et c), а затем использовать этот id в качестве источника ссылки ИЛИ вы вам придется перенастроить ваш API, чтобы использовать это свойство oid в качестве параметра URL-адреса для сопоставления (вместо 1.json он будет использовать oid в качестве параметра URL-адреса для сопоставления и будет 5e579cdfe99bdd0ca1cf64a3.json).

Например, эта конечная точка API (которая происходит от http://jsonplaceholder.typicode.com) содержит свойство id, которое используется в качестве параметра URL-адреса для получения c JSON файл по его id (обратите внимание, как оба URL и JSON данные содержат id из 9) .

Кстати, если вы используете Chrome, вы можете установить это расширение до ttify / format 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), упомянутую в предыдущем абзаце, а также реализует некоторые из следующих js методов выборки данных (исключен getStaticPaths для простоты; однако технически он может заменить getServerSideProps в динамике c pages / users / [id]. js page поскольку данные никогда не будут изменены / обновлены во время выполнения):

репозиторий с примером данных

...