MST

星途 面试题库

面试题:Next.js 中 getServerSideProps 与其他数据获取方法的深度对比及应用选择

在 Next.js 应用开发中,除了 getServerSideProps 外,还有诸如 getStaticProps、Infinite Scroll 等数据获取方式。请详细对比 getServerSideProps 与这些方式在数据获取时机、适用场景、SEO 友好度、数据一致性等方面的差异,并举例说明在不同业务需求下如何准确选择合适的数据获取方法。
12.3万 热度难度
前端开发Next.js

知识考点

AI 面试

面试题答案

一键面试

getServerSideProps 与其他方式对比

  1. 数据获取时机

    • getServerSideProps:在每次请求页面时获取数据,在服务器端运行。
    • getStaticProps:在构建时获取数据,并将其包含在生成的静态 HTML 中,也可在重新验证时在服务器端更新数据。
    • Infinite Scroll(以 Next.js 13 中的 useInfiniteQuery 为例,基于 React Query):根据用户滚动动态获取数据,在客户端执行。
  2. 适用场景

    • getServerSideProps:适用于需要实时数据的场景,如显示用户特定的、不断变化的数据(如用户的最新订单)。
    • getStaticProps:适合内容变化不频繁的数据,如博客文章、产品信息页面等。
    • Infinite Scroll:适用于大量数据分页展示场景,用户滚动时按需加载数据,如社交媒体动态流。
  3. SEO 友好度

    • getServerSideProps:由于每次请求都在服务器端获取数据,搜索引擎爬虫访问时可获取最新数据,SEO 友好,但性能上相对 getStaticProps 稍逊。
    • getStaticProps:构建时生成静态 HTML,搜索引擎爬虫易于抓取,SEO 非常友好。
    • Infinite Scroll:初始页面加载时数据有限,对 SEO 不太友好,需额外处理(如服务器端渲染初始数据)。
  4. 数据一致性

    • getServerSideProps:每次请求都获取最新数据,数据一致性高。
    • getStaticProps:构建时获取数据,若未配置重新验证,数据一致性低;配置重新验证后可在一定程度上保证数据一致性。
    • Infinite Scroll:数据一致性取决于 API 数据更新频率和客户端获取逻辑,通常数据一致性较高,但初始加载数据可能非最新。

不同业务需求下选择合适方法

  1. 实时数据需求:如显示股票价格实时变化

    export async function getServerSideProps(context) {
      const response = await fetch('https://api.example.com/stock-price');
      const data = await response.json();
      return {
        props: {
          stockPrice: data.price
        }
      };
    }
    
    const StockPage = ({ stockPrice }) => (
      <div>Current Stock Price: {stockPrice}</div>
    );
    
    export default StockPage;
    
  2. 静态内容展示:如博客文章展示

    export async function getStaticProps() {
      const response = await fetch('https://api.example.com/blog-posts/1');
      const data = await response.json();
      return {
        props: {
          blogPost: data
        },
        revalidate: 60 * 60 * 24 // 每天重新验证
      };
    }
    
    const BlogPostPage = ({ blogPost }) => (
      <div>
        <h1>{blogPost.title}</h1>
        <p>{blogPost.content}</p>
      </div>
    );
    
    export default BlogPostPage;
    
  3. 大量数据分页展示:如社交媒体动态流

    import { useInfiniteQuery } from '@tanstack/react-query';
    import React from'react';
    
    const fetchPosts = async ({ pageParam = 0 }) => {
      const response = await fetch(`https://api.example.com/social - posts?page=${pageParam}&limit=10`);
      return await response.json();
    };
    
    const SocialFeed = () => {
      const { data, fetchNextPage, hasNextPage } = useInfiniteQuery({
        queryKey: ['social - posts'],
        queryFn: fetchPosts,
        getNextPageParam: (lastPage, allPages) => {
          return allPages.length;
        }
      });
    
      return (
        <div>
          {data?.pages.flatMap(page => page.posts).map(post => (
            <div key={post.id}>
              <p>{post.content}</p>
            </div>
          ))}
          {hasNextPage && (
            <button onClick={() => fetchNextPage()}>Load More</button>
          )}
        </div>
      );
    };
    
    export default SocialFeed;