面试题答案
一键面试getServerSideProps 与其他方式对比
-
数据获取时机
- getServerSideProps:在每次请求页面时获取数据,在服务器端运行。
- getStaticProps:在构建时获取数据,并将其包含在生成的静态 HTML 中,也可在重新验证时在服务器端更新数据。
- Infinite Scroll(以 Next.js 13 中的 useInfiniteQuery 为例,基于 React Query):根据用户滚动动态获取数据,在客户端执行。
-
适用场景
- getServerSideProps:适用于需要实时数据的场景,如显示用户特定的、不断变化的数据(如用户的最新订单)。
- getStaticProps:适合内容变化不频繁的数据,如博客文章、产品信息页面等。
- Infinite Scroll:适用于大量数据分页展示场景,用户滚动时按需加载数据,如社交媒体动态流。
-
SEO 友好度
- getServerSideProps:由于每次请求都在服务器端获取数据,搜索引擎爬虫访问时可获取最新数据,SEO 友好,但性能上相对 getStaticProps 稍逊。
- getStaticProps:构建时生成静态 HTML,搜索引擎爬虫易于抓取,SEO 非常友好。
- Infinite Scroll:初始页面加载时数据有限,对 SEO 不太友好,需额外处理(如服务器端渲染初始数据)。
-
数据一致性
- getServerSideProps:每次请求都获取最新数据,数据一致性高。
- getStaticProps:构建时获取数据,若未配置重新验证,数据一致性低;配置重新验证后可在一定程度上保证数据一致性。
- Infinite Scroll:数据一致性取决于 API 数据更新频率和客户端获取逻辑,通常数据一致性较高,但初始加载数据可能非最新。
不同业务需求下选择合适方法
-
实时数据需求:如显示股票价格实时变化
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;
-
静态内容展示:如博客文章展示
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;
-
大量数据分页展示:如社交媒体动态流
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;