目录 介绍 设置项目 了解文件夹结构 列出所有博客文章 展示单个博客文章 在 Next.js 中利用加载 UI 和流式传输 结论 参考 一、简介 你好呀! 在今天的教程中,我们将开始使用 Next.js 创建一个简单但功能强大的博客的旅程。 无论您是 Next.js 的新手,还是只是想温习一些基础知识,本指南都是为您量身定制的。 我们不仅会讨论如何设置项目,还会涉及文件夹结构、服务器端渲染等。 您可以 找到完整的存储库 在这里 让我们开始吧! 2. 设置项目 第 1 步:创建应用程序 首先,让我们使用以下命令来设置 Next.js 应用程序: npx create-next-app@latest blog-example 完成后,导航到新创建的项目: cd blog-example 第2步:启动开发服务器 尽管我在本指南中使用的是 ,但请随意使用 或 : yarn npm pnpm yarn dev 现在,访问 ,您将在其中找到默认的 Next.js 模板页面。 http://localhost:3000 3. 了解文件夹结构 此时,了解 Next.js 应用程序的结构很有帮助。请参阅下图以直观地了解文件夹布局。 4. 列出所有博客文章 4.1. API路线 在 内,我们将为博客文章设置一个虚拟 API。这里, 指定我们希望每 60 秒重新验证一次数据。 /app/api/posts/route.js next: { revalidate: 60 } 重新验证数据 重新验证是清除数据缓存并重新获取最新数据的过程。当您的数据发生变化并且您希望确保显示最新信息时,这非常有用。 可以通过两种方式重新验证缓存的数据: :经过一定时间后自动重新验证数据。这对于不经常更改且新鲜度不那么重要的数据很有用。 基于时间的重新验证 :根据事件(例如表单提交)手动重新验证数据。按需重新验证可以使用基于标签或基于路径的方法立即重新验证数据组。当您想要确保尽快显示最新数据时(例如,当更新无头 CMS 的内容时),这非常有用。 按需重新验证 基于时间的重新验证 要定期重新验证数据,可以使用 的 选项来设置资源的缓存生命周期(以秒为单位)。 fetch next.revalidate 这是一个例子: import { NextResponse } from 'next/server' export async function GET() { const res = await fetch('https://dummyjson.com/posts', { next: { revalidate: 60 }, }); const data = await res.json(); return NextResponse.json(data); } 4.2.显示帖子 让我们创建一个组件 ,它从我们的服务器获取并显示帖子。虽然我的风格很简约,但请随意让它变得有趣! PostsPage export default async function PostsPage() { const res = await fetch('http://localhost:3000/api/posts'); const { posts } = await res.json(); return ( // Styles are for readability; customize as you wish! <div> <h1>All Blog Posts</h1> <hr style={{ width: '220px' }} /> <div style={{ paddingTop: '40px' }}> {posts.map(post => ( <article key={post.id}> <h2>{post.title}</h2> <p style={{ paddingBottom: '30px'}}>{post.body}</p> </article> ))} </div> </div> ); } 到目前为止,您应该看到一个文章列表。 5.展示一篇博客文章 5.1.链接帖子 为了使每个帖子标题可点击,我们将从 Next.js 添加 组件: Link import Link from 'next/link'; export default async function PostsPage() { // ... rest of the code return ( <div> // ... rest of the code <div style={{ paddingTop: '40px' }}> {posts.map(post => ( <article key={post.id}> <Link href={`posts/${post.id}`}> <h2>{post.title}</h2> </Link> <p style={{ paddingBottom: '30px'}}>{post.body}</p> </article> ))} </div> </div> ); } 5.2.单个帖子的 API 路由 在 Next.js API 路由中,我们根据 ID 获取特定帖子: import { NextResponse } from 'next/server' export async function GET(request, { params }) { const { id } = params; const res = await fetch(`https://dummyjson.com/posts/${id}`, { next: {revalidate: 60} }); const post = await res.json(); return NextResponse.json({ post }); } 5.3.显示单个帖子 为了显示单个帖子,了解 Next.js 中服务器和客户端组件之间的差异至关重要。 给定的组件 使用客户端数据获取。 SinglePost 本质上,这意味着在页面渲染后在客户端获取数据。它允许丰富的交互性而不牺牲性能。有关这方面的更多信息,请参阅 。 React Essentials 上的 Next.js 文档 客户端组件 客户端组件使您能够向应用程序添加客户端交互性。在 Next.js 中,它们在服务器上 并在客户端上进行水化。您可以将客户端组件视为 中的组件一直以来的工作方式。 预渲染 页面路由器 'use client' import Link from 'next/link'; import { useEffect, useState } from 'react'; export default function SinglePost({params}) { const [post, setPost] = useState(null); const fetchPost = async (id) => { const res = await fetch(`http://localhost:3000/api/posts/${id}`); const {post} = await res.json(); post && setPost(post); } useEffect(() => { fetchPost(params.id); }, []) return ( <div style={{ paddingTop: '20px', paddingLeft: '20px' }}> <Link href='/'>Back to home</Link> <div style={{ paddingTop: '50px' }}> <article> <h1 style={{ paddingBottom: '10px' }}>{post?.title}</h1> {post?.tags.map((tag, index) => <span style={{ fontWeight: 'lighter' }} key={index}>{tag} | </span>)} <br/> <p style={{ paddingTop: '10px' }}>{post?.body}</p> </article> </div> </div> ) } 现在,您应该能够看到文章的详细信息。造型不足的地方还请见谅! 6. 在 Next.js 中使用加载 UI 和流 为了增强用户体验,请考虑添加加载组件。 Next.js 提供了带有加载 UI 和流媒体的内置解决方案。它有助于显示加载旋转器,直到您的内容准备就绪。阅读 深入了解。 提示: 有关加载 UI 和流媒体的官方指南, 例如: // You can add any UI inside Loading, including a Skeleton. export default function Loading() { return <LoadingSkeleton />} 七、结论 构建 Next.js 应用程序既有趣又富有启发性。 我们已经学会了设置项目、管理文件夹结构、列出博客文章、展示单个帖子,甚至触及加载状态。 随着 Next.js 在 Web 开发社区中的快速发展,在这里学到的技能非常宝贵。 在此基础上进行扩展,探索更多功能,祝您编码愉快! 8. 参考文献 Next.js 官方文档 对于文章的数据,我使用了 DummyJson 为了构建这篇文章,我使用了 StackEdit 感谢您抽出时间并致力于学习。您的反馈非常有价值。如果您对本文有任何补充或更正,请联系我们。 通过以下方式与我联系: 社区 dev.to @leandro_nnz 社区 hackernoon.com @leandronnz 推特 @digpollution 干杯!