如何在 Next.js 中获取组件内的类别页面数据?

How to fetch category page data inside component in Next.js?

我想创建一个类别页面,其中包含添加到文章的所有标签。单击标签时,它应该会显示一个页面,其中包含包含该特定标签的所有文章。

我正在使用 Next.js、SSG,并使用以下 GraphQL 查询从 Contentful 获取文章:

export async function getArticles() {
  const articlesQuery = gql`
    {
      articleCollection {
        items {
          title
          slug
          excerpt
          date
          contentfulMetadata {
            tags {
              name
              id
            }
          }
          featuredImage {
            title
            url
            width
            height
          }
        }
      }
    }
  `;
  return graphQLClient.request(articlesQuery);
}

contentfulMetadata 是标签的来源:

contentfulMetadata {
    tags {
        name
        id
    }
}

然后我创建了一个 CategorySection 组件:

import styled from "styled-components";
import { getArticles } from "../../utils/contentful";
import Link from "next/link";

export async function getStaticProps() {
  const categories = await getArticles();

  return {
    props: {
      categories: categories.articleCollection.items,
    },
  };
}

export default function CategorySection({ categories }) {
  return (
    <Wrapper>
      <ContentWrapper>
        <CategoryWrapper>
          {categories.map((category) => {
            return (
              <Link href={`/articles/categories/${category.tags.name}`}>
                <Categories key={category.tags.id}>
                  {category.tags.name}
                </Categories>
              </Link>
            );
          })}
        </CategoryWrapper>
      </ContentWrapper>
    </Wrapper>
  );
}

CategorySection 组件给我以下错误消息:

TypeError: Cannot read property 'map' of undefined"

下面是我的 /pages/articles/categories/[slug].jsx 文件:

import styled from "styled-components";
import { getArticles, getArticle } from "../../utils/contentful";

export async function getStaticPaths() {
  const data = await getArticles();

  return {
    paths: data.articleCollection.items.map((article) => ({
      params: { slug: article.contentfulMetadata.tags.id },
    })),
    fallback: false,
  };
}

export async function getStaticProps(context) {
  const data = await getArticle(context.params.slug);

  return {
    props: { article: data.articleCollection.items[0] },
  };
}

export default function Category({ article }) {
  return <h1>{article.contentfulMetadata.tags.name}</h1>;
}

我收到以下错误:

Error: A required parameter (slug) was not provided as a string in getStaticPaths for /articles/categories/[slug]

你能帮我理解如何从我的类别(标签)创建动态页面吗?

getStaticProps 只能在页面组件中使用,因此在您的情况下,它会在您的 CategorySection 组件中被完全忽略。您需要在页面级别获取数据并将其传递给要使用它的组件。


一个可能的解决方案是简单地将数据作为 prop 传递给所需的组件。

// pages/article

import { getArticles } from "../../utils/contentful";

export async function getStaticProps() {
    const categories = await getArticles();

    return {
        props: {
            categories: categories.articleCollection.items
        }
    };
}

export default function ArticlePage({ categories }) {
    return (
        <CategorySection categories={categories} />
    );
}