【问题标题】:Nextjs not correctly load GetStaticProps and not return props to pageNextjs 没有正确加载 GetStaticProps 并且没有将道具返回到页面
【发布时间】:2022-01-31 01:50:11
【问题描述】:

我无法在 Next.js/React 项目中调用 getStaticProps 函数。我想在页面路径更改为/blog 时加载getStaticProps 所以在我的pages/blogs

type BlogStaticInputs = {
    blogs: BlogsType[]
}

export const getStaticProps: GetStaticProps = async () => {
    console.log('hello')
    const blogs = getAllBlogs(['date', 'slug', 'title'])

    return {
        props: { blogs }
    }
}

export const Index = ({ blogs }: BlogStaticInputs) => {
    return <Blogs blogs={blogs} />
}

export default Index

而我的BlogType

export type BlogType = {
    date?: string
    slug: string
    title: string
}

而且我在控制台中看不到console.log('hello'),所以我认为getStaticProps 目前没有工作。

在我的_app.tsx - 我认为这是正确加载道具和组件。

function MyApp({ Component, pageProps }: AppProps) {

    return (
        <>
            <Component {...pageProps} />
        </>
    )
}

export default MyApp

而我的getAllBlogs 看起来像这样

export function getAllBlogs(fields: string[] = []): BlogItems[] {
    console.log('I am getting blogs now...')
    const slugs = getBlogSlugs()
    const posts = slugs
        .map((slug) => getBlogBySlug(slug, fields))
        // sort posts by date in descending order
        .sort((post1, post2) => (post1.date > post2.date ? -1 : 1))
    return posts
}

和支持的功能就是这些。

export function getBlogSlugs(): string[] {
    return fs.readdirSync(POSTS_PATH)
}

type BlogItems = {
    [key: string]: string
}

export function getBlogBySlug(slug: string, fields: string[] = []): BlogItems {
    const realSlug = slug.replace(/\.mdx$/, '')
    const fullPath = join(POSTS_PATH, `${realSlug}.mdx`)
    const fileContents = fs.readFileSync(fullPath, 'utf8')
    const { data, content } = matter(fileContents)

    const items: BlogItems = {}

    // Ensure only the minimal needed data is exposed
    fields.forEach((field) => {
        if (field === 'slug') {
            items[field] = realSlug
        }
        if (field === 'content') {
            items[field] = content
        }
        if (data[field]) {
            items[field] = data[field]
        }
    })

    return items
}

以及获取博客目录路径的支持功能

export const POSTS_PATH = path.join(process.cwd(), 'blogs')

我认为 getAllBlogs 函数尚未调用,因为我看不到 console.log('I am getting blogs now...')

【问题讨论】:

  • getAllBlogs 函数是什么样子的?
  • 我添加了getAllBlog函数!在调用`return 之前,我尝试在我的export const Index 函数中使用console.log(blogs),参数博客仍然是空的
  • 确保以下几点: 1) 确保getStaticProps 是从页面组件(pages 文件夹下的组件)导出的; 2) 检查您启动开发服务器的终端是否有 getStaticProps 内的任何 console.logs - getStaticProps 在服务器上运行,因此这些不会出现在浏览器的控制台中。

标签: reactjs typescript next.js


【解决方案1】:

在开始使用更强类型的解决方案之前,我确实注意到您的 BlogType 类型在 pages/index.tsx 文件中被重命名为 BlogTypes?末尾的s 是否引用了与BlogType 相同的类型?

// BlogType
export type BlogType = {
    date?: string
    slug: string
    title: string
}

// versus

// In your Index (pages/index.tsx) file
type BlogStaticInputs = {
    blogs: BlogsType[]
}

无论如何,我将继续使用上面定义的BlogType 类型。

首先,如果您使用src 设置,请在根目录或 src 目录中的 types 目录中定义它。

/**
 * @type {ParsedUrlQuery}
 * @description url query params
 */
export type ParsedUrlQuery<T = string, N = NodeJS.Dict<T | T[]>> = N;

我做过类似的事情,我想我看到了这个问题。只需添加一些使用 Next+TypeScript 的额外提示(我一年多以来的专长是 Nextjs + 无头 wordpress 构建)

ParsedUrlQuery 类型可以与GetStaticPropsGetStaticPathsGetServerSideProps 一起使用。

对于这类情况,这是一个可重用且有用的组件。我使用 Tailwindcss 作为我的样式框架来编写它,所以如果您使用其他东西,只需替换 className 的内容即可

import { FC } from "react";

const DataInspector: FC = ({ children }) => {
  return (
    <div
      lang='json'
      className='font-gothamLight container max-w-7xl break-normal'>
      <pre className='container flex-col mx-auto text-[12px] bg-[#151515] text-yellow-400 w-8xl max-w-8xl overflow-x-hidden'>
        {JSON.stringify(children, null, 2)}
      </pre>
    </div>
  );
};

export default DataInspector;

一旦定义好,用GetStaticProps 试试——如果你没有正确传递已建立的类型,它会出错。您还可以看到返回给客户端的推断类型,如下所示:

import type {
  GetStaticPropsContext,
  GetStaticPropsResult,
  InferGetStaticPropsType
} from "next";
// update import paths below accordingly
import type { ParsedUrlQuery } from "@/types/index";
import type { BlogType } from "@/types/blog-type";
import DataInspector from "@/components/data-inspector";

type BlogStaticInputs = {
    blogs: BlogType[]
}

// try hovering over `blogs` -- you'll notice it's strongly typed
export default function Index<T extends typeof getStaticProps>({
  blogs
}: InferGetStaticPropsType<T>) {
    const tempErrObj = { error: new Error(`[Blogs data handling error]: ${blogs}`).message };
    return (
    <>
      {blogs && blogs.length > 0 
        ? <Blogs blogs={blogs} /> 
        : <DataInspector>{blogs ? blogs : tempErrObj}</DataInspector>
      }
    </>
   );
}

export const getStaticProps = async (
  ctx: GetStaticPropsContext<ParsedUrlQuery>
): Promise<GetStaticPropsResult<BlogStaticInput>> => {

   const blogs = getAllBlogs(['date', 'slug', 'title']);

    return {
        props: { blogs }
    };
}

【讨论】:

    猜你喜欢
    • 2021-03-22
    • 2015-07-19
    • 1970-01-01
    • 2022-10-25
    • 2015-07-31
    • 2021-11-13
    • 2015-08-28
    • 1970-01-01
    相关资源
    最近更新 更多