最近几个月,我认识了
React
和Next.js
还有Typescript
这几个技术栈,可以说是在我对 Web 探索的道路上一个不可或缺的里程碑。我是在这里学到的 👇
其实在最初,只是老师提出的一个新的项目:一个属于自己的 OJ 系统,可以在里面打自己的比赛。但是,应该用什么框架做出来呢?在很久之前,我接触过 mdui 这个样式库,它提供了很多美丽的 Material Design 的组件,让我知道了
<div>
是多么神奇,所以我就用它和最基本的 .html
文件编写了一个自己第一个在 Github Pages 上的网站。但是在不同页面中,例如有一个主页和一个关于页,这里有一个最头疼的问题,来举一个例子。假如这里有一个
Home
页面和一个 About
页面 ,它们都有一个导航栏,导航栏上的链接都指向了另一个页面,就像这样:

看起来很不错。但一切总不那么一帆风顺。假如有一天,我增加了一个新的页面,叫做
Download
,现在,我把Home
复制一下,作为这个新的Download
页。
这时候,每个页面的导航栏都需要再加一个链接,这样我才能够访问到
Download
页,该怎么做呢?你可能马上想到 “每一个页面都加上访问到Download
的链接呗!” 嗯,当初我也是这么想的。所以,现在我需要给每一个页面的导航栏上都加上一个链接。就像这样:

现在我们的确添加上了
Download
页面,让我们来回顾一下步骤- 复制
Home
页面,作为Download
页面的模板
- 更改
Home
页面的导航栏,添加指向Download
页的链接
- 更改
About
页面的导航栏,添加指向Download
页的链接
- 更改
Download
页面的导航栏,添加指向About
页的链接
等等。这是不是太繁琐了?假如我有 4个,5个,乃至 99 个页面,是不是我都要这么做,对每个页面都加上链接呢?这就是传统 html 对编写一个网站的局限性之一。
为了解决这个问题,我们需要把这个导航栏变成一个文件,让它在其他页面应用起来,当有新的页面的时候,我只需要动一下导航栏的代码就可以了。这就是
组件化
React 正是利用了这个特点,它将页面分为一个个组件,每一个组件都具有复用性,也就是说,你可以只写一次导航栏,然后在每个页面都引用上它。甚至,你还可以把页面作为一个组件,页面组件里包含一个导航栏。

现在看起来很不错。但是要怎样才能每一个 Page 具有独一无二的内容呢?Navbar 中的链接该怎样展示出来?现在,你需要的是数据。
你可能会想到,“直接
for
循环一个数组,数组里包含链接不就好了吗?“ 的确,这是最能想到的办法,但在 React 的核心设计思想中,更强烈推荐的是声明式编程
即开发者描述应该渲染什么,而不是如何去渲染,这种设计方式使得代码更加简洁、易于理解和维护。所以,对于在 React 中展示数据,可以用到数组的
map
函数。回到刚刚的例子,现在我们来定义一个导航栏中应该有哪些链接。可以使用
interface
定义一个链接的属性,每一个链接就是一个object(对象)
,具有名称和链接地址,然后我们再创建一个数组,每一项都是一个object(对象)
。接下来,一切都好办了,在 Navbar 中对这些数据通过
map
进行展示即可。下面就是我们的流程。
在代码中,创建一个函数式 React 组件(Navbar),然后返回这个组件需要渲染的内容(也就是导航栏),导航栏里的链接就是通过
map
遍历数据展示出来的。解释一下
- 在 React 中,可以用
JSX
语法表示html
中的标签(DOM)。
- 用
{}
括起来的数据就是表达式,比如navbarLinks.map()
就是一个表达式,再例如这个map
函数获得到每个链接(link
)的href
,name
都是一个表达式。而for
不是。这便体现了声明式编程。
- React 还具有虚拟DOM的特性,虚拟DOM是对真实DOM的一种抽象和模拟。 当虚拟DOM发生变化时,它会与之前的虚拟DOM树进行对比,然后计算出最小的变化集。所以,我们需要给每一个链接都加上
key
属性,不论数据怎么变化,它就可以从每个DOM中的key
来辨认是新朋友还是老伙计,而不是再次遍历所有数据。
下面,我们就需要把 Navbar 放入到每一个页面中,一个新的问题又出现了:“如何处理页面之间的跳转?”回到文章最初,我还发现了 Django 这样一个使用 Python 实现的用于构建网站的框架(我还没有认识React),它相当于把前端和后端都集成到了一起,当初放弃了。后来,学完 React脚手架 我发现了 Next.js ,它就是一个对于我而言一个理想的用于构建网站的框架,每一个页面都是一个 React 组件,并且具有 SSR(服务端渲染)等特性,同时提供了丰富的工具和内置组件,例如对图片进行优化展示的 Image 组件,Cookie,LocalStorage等。
全栈开发
Next.js 中的每一个页面为一个 page 组件,也就是对应访问的每一个
html
,我们还可以通过文件夹的方式表示页面父子关系。此外,每一个页面都具有一个 layout 组件,相当于这个 page 的样式,比如为其设置标题、字体等。在其官方文档中是这样展示的。
既然 layout 是一个组件,我们就可以利用 React 组件的复用性,引用并且将 Navbar 添加到 layout 中,也就是

现在,创建好
download
和about
文件夹,并且在两个文件夹里面加上page.tsx
,这样就实现了我们当初的愿望:在每一个页面显示 Navbar,并且当有更改时不必修改每一个页面。就像你现在看到 Choneas 的个人网站上有一个始终在页面顶端的导航栏,和这个文章的标题。总结
这篇文章并不是一个“如何构建一个网站”的教程,而是通过一个例子简要描述了我是如何一步步了解 Web 开发的,我觉得它可以作为对 Web 开发之路的一个小小的引路灯,在“自学”中找到下一步应该了解什么。这也是我的第一篇比较正式的小文章吧,他可能有很多缺少学术性的语句,或者里面怎么看都不是很中二的内容可能在我长大后看起来很中二。不论怎样,希望对你有所帮助,欢迎通过“评论”来告诉我。❤️🪶
接下来
如果要构建一个真正的项目,你还可以在 Navbar 里加上一个头像,一个搜索框,或者通过 MongoDB、Supabase 之类的第三方库实现一个用户系统;还可以使用 AntDesign 、HeroUI、Tailwindcss 或者 MDUI 等等为你的网站加上好看的样式和赏心悦目的组件;你还可以使用 
通过 Markdown 实现一个博客系统,这个文章是否为草稿,这个文章的第二个简介,都由你说了算;你也可以用 next-intl 为你的网站实现国际化。
next-mdx-remote
Github
next-mdx-remote
Owner
hashicorpUpdated
Mar 20, 2025这一切都是一个不断发现的过程,在未来,或许能有更好的解决方案,例如最近新出的 Turbo 。它旨在替代 Webpack,为 Next.js 的开发环境带来更快的构建速度和更高效的开发体验。有更多的事情正在发生。
我唯一知道的事情就是我一无所知。——苏格拉底