MST

星途 面试题库

面试题:Next.js 中如何在动态路由页面实现静态生成并获取动态数据

假设你有一个博客系统,文章页面的路由是 /posts/[id],请描述如何结合 Next.js 的动态路由与静态生成来实现该页面的静态生成,并且在构建时能够获取到对应文章的具体数据(如文章标题、内容等)。
44.9万 热度难度
前端开发Next.js

知识考点

AI 面试

面试题答案

一键面试
  1. 创建动态路由页面
    • 在 Next.js 项目的 pages 目录下创建 posts 文件夹,然后在该文件夹中创建 [id].js 文件。这个文件将处理特定文章的动态路由。
  2. 使用 getStaticProps 进行静态生成
    • [id].js 文件中,导出一个 getStaticProps 函数。这个函数在构建时运行,用于获取特定文章的数据。
    • 例如,假设文章数据存储在一个数据库(这里以 JSON 文件模拟),可以这样实现:
    import React from'react';
    import { getAllPostsData } from '../../lib/api';
    
    const Post = ({ post }) => {
      return (
        <div>
          <h1>{post.title}</h1>
          <p>{post.content}</p>
        </div>
      );
    };
    
    export async function getStaticProps(context) {
      const allPostsData = await getAllPostsData();
      const post = allPostsData.find(post => post.id === context.params.id);
      return {
        props: {
          post
        },
        revalidate: 60 * 60 * 24 // 每 24 小时重新验证(可选,如果需要增量静态再生)
      };
    }
    
    export async function getStaticPaths() {
      const allPostsData = await getAllPostsData();
      const paths = allPostsData.map(post => ({
        params: { id: post.id.toString() }
      }));
      return { paths, fallback: false };
    }
    
    export default Post;
    
    • getStaticPaths 函数用于告诉 Next.js 要预渲染哪些路径。它返回一个包含所有文章 idpaths 数组,fallback 设置为 false 表示如果用户请求的路径不在 paths 中,返回 404 页面。
    • getStaticProps 函数通过 context.params.id 获取当前文章的 id,然后从所有文章数据中找到对应的文章数据,并将其作为 props 传递给组件。
  3. 数据获取函数 getAllPostsData
    • lib/api.js(这里假设的路径)文件中实现 getAllPostsData 函数,用于从数据源(如 JSON 文件、数据库等)获取所有文章数据。
    • 例如,如果数据存储在 JSON 文件中:
    import path from 'path';
    import fs from 'fs';
    
    export function getAllPostsData() {
      const postsDirectory = path.join(process.cwd(), 'posts');
      const fileNames = fs.readdirSync(postsDirectory);
      const allPostsData = fileNames.map(fileName => {
        const id = fileName.replace(/\.md$/, '');
        const fullPath = path.join(postsDirectory, fileName);
        const fileContents = fs.readFileSync(fullPath, 'utf8');
        // 假设 JSON 格式数据
        const data = JSON.parse(fileContents);
        return {
          id,
         ...data
        };
      });
      return allPostsData;
    }
    

通过上述步骤,结合 Next.js 的动态路由与静态生成,就可以实现文章页面的静态生成,并在构建时获取到对应文章的具体数据。