我们在项目中使用 Next.js 时,不再从 unpkg.com 加载 react
and react-dom
脚本。直接使用 npm
或首选的包管理器在本地安装这些包。
注意:要使用Next.js,您需要在计算机上安装Node.js版本 18.17.0 或更高版本
我们直接在 index.html
文件相同的目录中创建一个新文件,该文件使用空对象 {}
名叫 package.json
。

在终端中,在项目的根目录中运行以下命令:
Shell
npm install react@latest react-dom@latest next@latest
安装完成后,能够看到 package.json
文件中列出了刚才安装的项目依赖项:
JSON
{
"dependencies": {
"next": "^14.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
如果版本比上面显示的版本更高也没事,只要您安装了 next
、 react
和 react-dom
软件包,就可以开始了。
您还会注意到一个名为 package-lock.json
新文件,其中包含有关每个包的确切版本的详细信息。
跳回 index.html
文件,可以删除以下代码:
<html>
和<body>
标记。id
是app
的<div>
元素。react
和react-dom
脚本,因为您已经使用 NPM 安装了它们。- 由于Next.js有一个编译器,可以将 JSX 转换为有效的 JavaScript,因此可以删除
bable
引用。 <script type="text/jsx">
标记document.getElementById()
和ReactDom.createRoot()
方法React.useState(0)
函数React.
的部分
删除上述行后,将以下导入添加到文件顶部:
JSX
import { useState } from 'react';
好,现在的代码如下:
JSX
import { useState } from 'react';
function Header({ title }) {
return <h1>{title ? title : 'Default title'}</h1>;
}
function HomePage() {
const names = ['张三', '李四', '王五'];
const [likes, setLikes] = useState(0);
function handleClick() {
setLikes(likes + 1);
}
return (
<div>
<Header title="你好" />
<ul>
{names.map((name) => (
<li key={name}>{name}</li>
))}
</ul>
<button onClick={handleClick}>Like ({likes})</button>
</div>
);
}
此时,index.html
里面保留的都了是JSX代码,你可以把index.html
改为index.js
或index.jsx
创建你的首页
Next.js使用文件系统路由。这意味着,您可以使用文件夹和文件,而不是使用代码来定义应用程序的路由。
以下是在Next.js中创建首页的方法:
- 创建一个名为 app 的新文件夹, 并将
index.js
文件移动到其中。 - 将文件
index.js
重命名为page.js
,这将是你的主页入口。 - 添加到
export default
到组件<HomePage>
中,以帮助Next.js区分要呈现为页面主要组件的组件。

JSX
import { useState } from 'react';
function Header({ title }) {
return <h1>{title ? title : 'Default title'}</h1>;
}
export default function HomePage() {
// ...
}
运行开发服务器
接下来,让我们运行开发服务器,以便在开发时查看新页面中的更改。将 "next dev"
脚本添加到文件 package.json
:
JSON
{
"scripts": {
"dev": "next dev"
},
"dependencies": {
"next": "^14.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
检查在终端中运行 npm run dev
会发生什么。您会注意到两件事:
-
运行完成后,会看到控制台报错了:
这是因为 Next.js 使用 React 服务器组件,这是一项允许 React 在服务器上渲染的新功能。服务器组件不支持
useState
,因此您需要改用客户端组件。这个我们后面会讲到
-
这时,你会发现
app
文件夹内自动创建一个名为的新layout.js
文件。这是应用程序的布局文件。您可以使用它来添加所有页面之间共享的 UI 元素(例如导航、页脚等)。JSXexport const metadata = { title: 'Next.js', description: 'Generated by Next.js', } export default function RootLayout({ children }) { return ( <html lang="en"> <body>{children}</body> </html> ) }
这边只是简要的引述了下路由和页面布局,详细的后面会出教程再讲。
服务端和客户端组件
在 Web 应用程序的上下文中:

- 客户端是指用户设备上的浏览器,它向服务器发送应用程序代码请求。然后,它将从服务器接收的响应转换为用户可以与之交互的接口。
- 服务器是指数据中心的计算机,用于存储应用程序代码、接收来自客户端的请求、执行一些计算并返回适当的响应。
无论哪个环境都有自己的功能和约束。例如,通过将页面渲染和一些数据放到服务器,可以减少发送到客户端的代码量,从而提高应用程序的性能。但是,要使 UI 具有交互性,我们就要更新客户端上的 DOM。
因此,服务器和客户端编写的代码并不总是相同的。某些操作(例如,获取数据或管理用户状态)更适合一种环境而不是另一种环境。
网络边界
网络边界是分隔不同环境的概念线。
在 React 中,您可以选择将网络边界放置在组件树中。例如,您可以在服务器上获取数据并渲染用户的帖子(使用服务器组件),然后在客户端上渲染每个帖子的交互内容LikeButton
(使用客户端组件)。
同样,您可以创建一个在服务器上渲染并跨页面共享的 Nav
组件,但如果要显示链接的活动状态,则可以在客户端上渲染 Links
列表。

在后台,组件被拆分为两个模块。服务器模块包含服务器上呈现的所有服务器组件,客户端模块包含所有客户端组件。
服务器组件渲染完成后,一种名为 React Server Component Payload(RSC)的特殊数据格式会被发送到客户端。
RSC 有效载荷包含
- 服务器组件的渲染结果。
- 客户端组件的占位符,用于显示客户端组件及其 JavaScript 文件的引用。
React 使用这些信息来整合服务器和客户端组件,并更新客户端上的 DOM。
让我们看看这是如何工作的。
使用客户端组件
Next.js默认使用服务器组件 - 这是为了提高应用程序的性能。
还记得刚才的报错吗?
Next.js警告您您正在尝试 useState
进入服务器组件。
您可以通过将交互式"赞"按钮移动到客户端组件来解决此问题。
在导出 LikeButton
组件的 app
文件夹中创建一个名为 like-button.js
的新文件:
JSX
export default function LikeButton() {}
将 <button>
元素和 handleClick()
函数移动 page.js
到新 LikeButton
组件:
JSX
export default function LikeButton() {
function handleClick() {
setLikes(likes + 1);
}
return <button onClick={handleClick}>Like ({likes})</button>;
}
接下来,移动 likes
状态和导入:
JSX
import { useState } from 'react';
export default function LikeButton() {
const [likes, setLikes] = useState(0);
function handleClick() {
setLikes(likes + 1);
}
return <button onClick={handleClick}>Like ({likes})</button>;
}
现在,要使 LikeButton
客户端组件成为客户端组件,请在文件顶部添加 React 'use client'
指令。这告诉 React 在客户端上渲染组件。
JSX
'use client';
import { useState } from 'react';
export default function LikeButton() {
const [likes, setLikes] = useState(0);
function handleClick() {
setLikes(likes + 1);
}
return <button onClick={handleClick}>Like ({likes})</button>;
}
回到您的 page.js
文件中,将 LikeButton
组件导入到您的页面中:
JSX
import LikeButton from './like-button';
function Header({title}) {
return <h1>{title ? title : 'Default title'}</h1>;
}
export default function HomePage() {
const names = ['张三', '李四', '王五'];
return (
<div>
<Header title="你好" />
<ul>
{names.map((name) => (
<li key={name}>{name}</li>
))}
</ul>
<LikeButton />
</div>
);
}
保存这两个文件后,后台会自动重新编译,你会发现浏览器自动刷新了。

这叫"快速刷新"。它使你在做的任何编辑时,结果会实时反馈。
今天只是简单的把Next.js进行安装和使用,后序会展开讲更多功能。