繁体   English   中英

从 Next JS 页面 api 通过 id 创建动态路由

[英]Create dynamic routes by id from Next JS pages api

我有一个页面,其中包含一个名为stories的对象列表,它以数组的形式显示我的所有故事。 我还有一个详细页面,其中显示了一个单独的故事

我想单击列表中任何给定故事的链接,然后它将导航到单个故事。 我想使用_id作为 URL 的动态部分,如下面的 GraphQL 所示。

我的 Graphql

export const listAllStories = () => {
  const query = gql`
    query StoryEntries($size: Int) {
      storyEntries(_size: $size) {
        data {
          _id
          _ts
          name
          premises{
            data{
              _id
              content
            }
          }
          createdAt
        }
      }
    }
  `

  return graphQLClient
      .request(query, { size: 999 })
      .then(({ storyEntries: { data } }) => data)
}

在我的页面 API 我有

export default async function handler(req, res) {
  const handlers = {
    GET: async () => {
      const storyEntries = await listAllStories()
      res.json(storyEntries)
    },
  }

  if (!handlers[req.method]) {
    return res.status(405).end()
  }

  await handlers[req.method]()
}

在我拥有的故事列表页面上

const ENTRIES_PATH = '/api/entries/allStories'

const useEntriesFlow = ({ initialEntries }) => {
    const { data: entries } = useSWR(ENTRIES_PATH, {
        initialData: initialEntries,
    })

    const EntryItem = ({ entry }) => (
         <>
            {entries?.map((entry) => (
                  {entry.name}
       <Link href="/story/[storyId]" as={`/story/${entry._id}`}>
                                <a>Go</a>
                            </Link>
             ))}
         </>
    )

export const getStaticProps = async () => ({
    props: {
        initialEntries: await listAllStories(),
    },
    revalidate: 1,
})

这很好并且有效。

**然后在我拥有的每个故事[storyId].js的详细信息页面上 **

export default function Story({story}) {

    const router = useRouter()
    const storyId = router.query.storyId
    return(
        <>
            <h5>hello {story._id}</h5>
        </>
    )
}

export const getStaticPaths = async () => {
    const res = await fetch(`${server}/api/entries/allStories/`);
    const { data } = await res.json();
    const paths = data.map(story => {
        return {
            params: { id: story._id.toString() }
        }
          // trying to get the _id from each story 
    })
    return {
        paths,
        fallback: false
    }
}

    export const getStaticProps = async (context) => {
    const { storyId } = context.query;    // Your dynamic page is [storyId].js
    const server = "http://localhost:3000";

    const res = await fetch(`${server}/api/entries/allStories/${storyId}`);
    // trying to get the params._id from each story
    console.log(res)
    const { data } = await res.json();
    return {
        props: { story: data }
    }
}

错误

TypeError: Cannot read properties of undefined (reading 'map')

问题

我要做的就是单击任何故事链接,然后通过_id将我带到详细信息页面。 我尝试了一些事情,但我做错了一些(或一些事情)。

任何帮助将不胜感激。

之后编辑。 我得到的错误。 我无法 map 我在 getStaticPaths 上的结果

在此处输入图像描述

export const getStaticProps = async (context) => {
    const { storyId } = context.query;    // Your dynamic page is [storyId].js
    const server = "YOUR SERVER VARIABLE";

    const res = await fetch(`${server}/api/entries/allStories/${storyId}`);
      // trying to get the params._id from each story
    const { data } = await res.json();
    return {
        props: { story: data }
    }
}

取消注释

const router = useRouter()
const storyId = router.query.storyId

// some helpful links
// https://nextjs.org/docs/basic-features/data-fetching#the-paths-key-required
// https://stackoverflow.com/questions/65783199/error-getstaticpaths-is-required-for-dynamic-ssg-pages-and-is-missing-for-xxx



export const getStaticPaths = async () => {
    const server = "http://localhost:3000";

    const data = await fetch(`${server}/api/entries/allStories/`).then(res => res.json() )

    const paths = data.map(({_id}) => ({
        params: { storyId: _id },
    }))

    return {
        paths,
        fallback: false
    }
}



export const getStaticProps = async (context) => {

    const storyId = context.params.storyId;    // Your dynamic page is [storyId].js
    const server = "http://localhost:3000";

    // const res = await fetch(`${server}/api/entries/allStories/${storyId}`);
    // trying to get the params._id from each story 
    // single api call (here)
    const res = await fetch(`${server}/api/entries/allStories/`);
    // removing const { data } because the data will be returned when calling res.json()
    const data = await res.json();
    // instead of the calling the single api (just a fix not recommended to access [0] directly )
    return {
        props: { story: data.filter(story => story._id === storyId)[0] }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM