一看就会的Next.js Pages Router版 -- Getting Started(一)

简介: 一看就会的Next.js Pages Router版 -- Getting Started

什么是 Next.js?

Next.js 是一个用于构建 Web 应用程序的框架。

借助 Next.js,您可以使用 React 组件构建用户界面。然后,Next.js 为您的应用程序提供额外的结构、功能和优化。

在幕后,Next.js 还为您抽象和自动配置工具,如捆绑、编译等(bundling, compiling, and more.)。这使您可以专注于构建应用程序,而不是花时间设置工具。

无论您是个人开发人员还是大型团队的一员,Next.js 都可以帮助您构建交互式、动态且快速的 Web 应用程序。

主要特点

Feature Description
Routing A file-system based router built on top of Server Components that supports layouts, nested routing, loading states, error handling, and more.一个基于文件系统的路由器,建立在服务器组件之上,支持布局、嵌套路由、加载状态、错误处理等。
Rendering Client-side and Server-side Rendering with Client and Server Components. Further optimized with Static and Dynamic Rendering on the server with Next.js. Streaming on Edge and Node.js runtimes.使用客户端和服务器组件的客户端和服务器端呈现。使用Next.js在服务器上进一步优化了静态和动态渲染。在Edge和Node.js运行时上流式传输。
Data Fetching Simplified data fetching with async/await support in React Components and the fetch()s API that aligns with React and the Web Platform.在React组件中使用async/await支持简化数据获取,并且fetch() API与React和Web平台保持一致。
Styling Support for your preferred styling methods, including CSS Modules, Tailwind CSS, and CSS-in-JS
Optimizations Improved Image Component with native browser lazy loading. New Font Module with automatic font optimization.改进的图像组件与本地浏览器延迟加载。新的字体模块与自动字体优化。
Typescript Improved support for TypeScript, with better type checking and more efficient compilation, as well as support for optional chaining and nullish coalescing. 改进了对TypeScript的支持,具有更好的类型检查和更高效的编译,以及对可选链接和空合并的支持。
API Reference Updates to the API design throughout Next.js. Please refer to the API Reference Section for new APIs.更新了整个Next.js的API设计。有关新的API,请参阅API参考部分。

如何使用这些文档

文档的章节和页面按顺序组织,从基础到高级,因此您可以在构建 Next.js 应用程序时逐步遵循它们。但是,您可以按任何顺序阅读它们或跳到适用于您的用例的页面。

在页面的右侧,您会看到一个目录,可以更轻松地在页面的各个部分之间导航。页面顶部的面包屑还会指示您是在查看 App Router 文档还是 Pages Router 文档。

To get started, checkout the Installation. If you're new to React or Server Components, we recommend reading the React Essentials page. 要开始,请检查安装。如果您是 React 或服务器组件的新手,我们建议您阅读 React Essentials 页面。

先决知识

尽管我们的文档旨在对初学者友好,但我们需要建立一个基线,以便文档可以专注于 Next.js 的功能。每当我们引入新概念时,我们都会确保提供相关文档的链接。

要充分利用我们的文档,建议您对 HTML、CSS 和 React 有基本的了解。如果您需要复习 React 技能,请查看以下资源:

辅助功能

为了在阅读文档时使用屏幕阅读器获得最佳的可访问性,我们建议使用 Firefox 和 NVDA,或者 Safari 和 VoiceOver。

If you have questions about anything related to Next.js, you're always welcome to ask our community on GitHub Discussions, Discord, Twitter, and Reddit.

React Essentials

要使用Next.js构建应用程序,熟悉React的新特性(如Server Components)会有所帮助。本页将介绍服务器和客户端组件之间的区别、何时使用它们以及推荐的模式。

如果你是React的新手,我们还建议你参考React文档。这里有一些很棒的学习资源:

Server Components

服务器和客户端组件允许开发人员构建跨服务器和客户端的应用程序,将客户端应用程序的丰富交互性与传统服务器呈现的改进性能相结合。

Thinking in Server Components

与React改变了我们构建ui的方式类似,React服务器组件引入了一种新的心智模型,用于构建利用服务器和客户端的混合应用程序。

React不再呈现整个应用程序的客户端(比如单页应用程序),而是让你可以根据组件的用途灵活地选择在哪里呈现组件。

For example, consider a page in your application: 例如,考虑应用程序中的一个页面:

image.png

如果我们将页面拆分为更小的组件,您将注意到大多数组件是非交互式的,并且可以作为服务器组件在服务器上呈现。对于较小的交互式UI,我们可以使用客户端组件。这与Next.js服务器优先的方法是一致的。

Why Server Components?

因此,您可能会想,为什么要使用服务器组件?与客户端组件相比,使用它们有什么优势?

服务器组件允许开发人员更好地利用服务器基础设施。例如,以前会影响客户端JavaScript包大小的大型依赖项可以完全保留在服务器上,从而提高性能。它们使编写React应用程序感觉类似于PHP或Ruby on Rails,但具有React的强大和灵活性以及用于模板UI的组件模型。

使用服务器组件,初始页面加载速度更快,并且减少了客户端JavaScript包的大小。基本客户端运行时的大小是可缓存和可预测的,并且不会随着应用程序的增长而增加。只有在通过客户端组件在应用程序中使用客户端交互时,才会添加额外的JavaScript。

当用Next.js加载路由时,初始HTML就会在服务器端呈现。然后这个HTML在浏览器中逐渐增强,允许客户端接管应用程序并添加交互性,通过异步加载Next.js和React客户端运行时。

To make the transition to Server Components easier, all components inside the App Router are Server Components by default, including special files and colocated components. This allows you to automatically adopt them with no extra work, and achieve great performance out of the box. You can also optionally opt-in to Client Components using the 'use client' directive.

为了更容易过渡到服务器组件,App Router中的所有组件默认都是服务器组件,包括特殊文件和配置的组件。这允许您自动采用它们,而不需要额外的工作,并获得开箱即用的出色性能。你也可以通过“use Client”指令选择加入客户端组件。

Client Components

Client Components enable you to add client-side interactivity to your application. In Next.js, they are pre-rendered on the server and hydrated on the client. You can think of Client Components as how components in the Pages Router have always worked.

客户端组件使您能够向应用程序添加客户端交互性。在Next.js中,它们在服务器上预渲染,并在客户端上进行渲染。您可以将客户端组件视为Pages Router中的组件一直以来的工作方式。

The "use client" directive

“use client”指令是一种约定,用于声明服务器组件和客户端组件模块图之间的边界。

js

复制代码

'use client';
import { useState } from 'react';
export default function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

image.png

“使用客户端”位于仅服务器和客户端代码之间。它被放置在文件的顶部,在导入的上方,以定义从仅服务器部分到客户机部分的边界的分界点。一旦在文件中定义了“use client”,导入其中的所有其他模块,包括子组件,都被视为客户端包的一部分。

Since Server Components are the default, all components are part of the Server Component module graph unless defined or imported in a module that starts with the "use client" directive.

由于服务器组件是默认的,所以所有组件都是服务器组件模块图的一部分,除非在以“use client”指令开头的模块中定义或导入。

Good to know:

  • Components in the Server Component module graph are guaranteed to be only rendered on the server.
  • Components in the Client Component module graph are primarily rendered on the client, but with Next.js, they can also be pre-rendered on the server and hydrated on the client.
  • The "use client" directive must be defined at the top of a file before any imports.
  • "use client" does not need to be defined in every file. The Client module boundary only needs to be defined once, at the "entry point", for all modules imported into it to be considered a Client component.

Server Component模块图中的组件保证只在服务器上呈现。

Client Component模块图中的组件主要在客户端上呈现,但是使用Next.js,它们也可以在服务器上预呈现,并在客户端上进行渲染。

在任何导入之前,必须在文件的顶部定义“use client”指令。

“use client”不需要在每个文件中都定义。客户端模块边界只需要在“入口点”定义一次,所有导入到其中的模块都被视为客户端组件。

When to use Server and Client Components?

为了简化在服务器组件和客户端组件之间的选择,我们建议使用服务器组件(默认在app目录中),直到你有了客户端组件的用例。

下表总结了服务器和客户端组件的不同用例:

What do you need to do? Server Component Client Component
Fetch data. ×
Access backend resources (directly) ×
Keep sensitive information on the server (access tokens, API keys, etc) ×
Keep large dependencies on the server / Reduce client-side JavaScript ×
Add interactivity and event listeners (onClick(), onChange(), etc) ×
Use State and Lifecycle Effects (useState(), useReducer(), useEffect(), etc) ×
Use browser-only APIs ×
Use custom hooks that depend on state, effects, or browser-only APIs ×
Use React Class components ×

Patterns

Moving Client Components to the Leaves

为了提高应用程序的性能,我们建议尽可能将客户端组件移动到组件树的叶子位置。

例如,你可能有一个布局,它有静态元素(如logo,链接等)和一个使用状态的交互式搜索栏。

与其把整个布局做成一个客户端组件,不如把交互逻辑移到一个客户端组件(例如<SearchBar />),并保持你的布局作为一个服务器组件。这意味着您不必将布局的所有Javascript组件发送到客户端。

app/layout.tsx
// SearchBar is a Client Component
import SearchBar from './searchbar';
// Logo is a Server Component
import Logo from './logo';
// Layout is a Server Component by default
export default function Layout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <>
      <nav>
        <Logo />
        <SearchBar />
      </nav>
      <main>{children}</main>
    </>
  );
}

Composing Client and Server Components

服务器组件和客户端组件可以组合在同一个组件树中。

在幕后,React处理渲染如下:

  • On the server, React renders all Server Components before sending the result to the client.
  • This includes Server Components nested inside Client Components.
  • Client Components encountered during this stage are skipped.
  • On the client, React renders Client Components and slots in the rendered result of Server Components, merging the work done on the server and client.
  • If any Server Components are nested inside a Client Component, their rendered content will be placed correctly within the Client Component.

在服务器端,React在将结果发送给客户端之前呈现所有服务器组件。

  • 这包括嵌套在客户端组件中的服务器组件。
  • 跳过此阶段遇到的客户端组件。

在客户端,React呈现客户端组件,并在服务器组件的呈现结果中插入插槽,合并在服务器和客户端上完成的工作。

  • 如果任何服务器组件嵌套在客户端组件中,它们呈现的内容将被正确地放置在客户端组件中。

Good to know:  In Next.js, during the initial page load, both the rendered result of Server Components from the above step and Client components are pre-rendered on the server as HTML to produce a faster initial page load

值得注意的是:在Next.js中,在初始页面加载期间,上述步骤中服务器组件和客户端组件的呈现结果都在服务器上预呈现为HTML,以产生更快的初始页面加载。

Nesting Server Components inside Client Components

鉴于上面概述的呈现流,将服务器组件导入到客户端组件有一个限制,因为这种方法需要额外的服务器往返。

Unsupported Pattern

不支持以下模式。你不能将服务器组件导入到客户端组件中:

app/example-client-component.tsx
'use client';
// This pattern will **not** work!
// You cannot import a Server Component into a Client Component.
import ExampleServerComponent from './example-server-component';
export default function ExampleClientComponent({
  children,
}: {
  children: React.ReactNode;
}) {
  const [count, setCount] = useState(0);
  return (
    <>
      <button onClick={() => setCount(count + 1)}>{count}</button>
      <ExampleServerComponent />
    </>
  );
}
Recommended Pattern: Passing Server Components to Client Components as Props

推荐模式:将服务器组件作为 props 传递给客户端组件

相反,在设计客户端组件时,你可以使用React props来标记服务器组件的“漏洞”。

服务器组件将在服务器上呈现,当客户端组件在客户端上呈现时,“洞”将被服务器组件的呈现结果填充。

一个常见的模式是使用React的children属性来创建“洞”。我们可以重构<ExampleClientComponent />以接受一个通用的子组件,并将<ExampleClientComponent />的导入和显式嵌套移动到父组件。

app/example-client-component.tsx
'use client';
import { useState } from 'react';
export default function ExampleClientComponent({
  children,
}: {
  children: React.ReactNode;
}) {
  const [count, setCount] = useState(0);
  return (
    <>
      <button onClick={() => setCount(count + 1)}>{count}</button>
      {children}
    </>
  );
}

现在,<ExampleClientComponent> 不知道 children 是什么。事实上,从它的角度来看,它甚至不知道子项最终将由服务器组件的结果填充。

ExampleClientComponent 的唯一责任是决定最终应该放置的任何子项。

在父服务器组件中,您可以导入 <ExampleClientComponent><ExampleServerComponent> 并将 <ExampleServerComponent> 作为 <ExampleClientComponent> 的子项传递:

app/page.tsx
// This pattern works:
// You can pass a Server Component as a child or prop of a
// Client Component.
import ExampleClientComponent from './example-client-component';
import ExampleServerComponent from './example-server-component';
// Pages in Next.js are Server Components by default
export default function Page() {
  return (
    <ExampleClientComponent>
      <ExampleServerComponent />
    </ExampleClientComponent>
  );
}

通过这种方法,<ExampleClientComponent><ExampleServerComponent>的呈现是解耦的,可以独立呈现——与服务器组件保持一致,服务器组件在客户端组件之前呈现在服务器上。

Good to know

  • This pattern is already applied in layouts and pages with the children prop so you don't have to create an additional wrapper component.
  • Passing React components (JSX) to other components is not a new concept and has always been part of the React composition model.
  • This composition strategy works across Server and Client components because the component that receives the prop has no knowledge of what the prop is. It is only responsible for where the thing that it is passed should be placed.
  • This allows the passed prop to be rendered independently, in this case, on the server, well before the Client Component is rendered on the client.
  • The very same strategy of "lifting content up" has been used to avoid state changes in a parent component re-rendering an imported nested child component.
  • You're not limited to the children prop. You can use any prop to pass JSX.

此模式已经应用于具有children属性的布局和页面中,因此您不必创建额外的包装器组件。

将React组件(JSX)传递给其他组件并不是一个新概念,并且一直是React组合模型的一部分。

这种组合策略可以跨Server和Client组件工作,因为接收props的组件不知道props是什么。它只负责它所传递的东西应该放在哪里。

这允许在客户端渲染客户端组件之前,在服务器上独立渲染传递的prop。

同样的“提升内容”策略也被用来避免父组件中的状态改变,从而重新呈现导入的嵌套子组件。

Passing props from Server to Client Components (Serialization)

Props passed from the Server to Client components need to be serializable. This means that values such as functions, Dates, etc, cannot be passed directly to client components.

从服务器传递到客户端组件的道具需要是可序列化的。这意味着函数、日期等值不能直接传递给客户端组件。

目录
相关文章
|
4月前
egg.js 24.3-24.5router路由相关
egg.js 24.3-24.5router路由相关
35 0
|
JavaScript 开发者 容器
Vue Router:构建交互性Vue.js应用的导航之道
在Vue.js应用程序开发中,导航是一个关键概念,它允许用户在不同视图之间进行无缝切换和交互。而Vue Router是Vue.js官方提供的路由管理库,为开发者提供了强大的工具来管理应用程序的导航和路由。在本博客中,我们将深入研究Vue Router的概念、核心功能、工作原理,以及如何使用Vue Router来构建具有高度交互性的Vue.js应用。
91 0
|
JavaScript CDN
【VUE】vue.js中的路由router
【VUE】vue.js中的路由router
|
29天前
|
JavaScript 前端开发 UED
揭秘Vue.js高效开发:Vue Router如何让单页面应用路由管理变得如此简单?
【8月更文挑战第30天】随着Web应用复杂性的增加,单页面应用(SPA)因出色的用户体验和高效的页面加载性能而备受青睐。Vue.js凭借简洁的语法和灵活的组件系统成为构建SPA的热门选择,其官方路由管理器Vue Router则简化了路由管理。本文通过实战示例介绍如何利用Vue Router实现高效的SPA路由管理,包括命名路由、动态路由及其核心优势。
16 0
|
11月前
|
JavaScript 前端开发 Go
Vue Router入门:为Vue.js应用添加导航
Vue Router入门:为Vue.js应用添加导航
78 0
|
JavaScript 数据安全/隐私保护 网络架构
Vue Router最佳实践,以确保你的Vue.js应用的路由管理清晰、可维护和高效
以下是使用Vue Router的最佳实践,以确保你的Vue.js应用的路由管理清晰、可维护和高效。
183 0
|
缓存 前端开发 JavaScript
一看就会的Next.js App Router版 -- Data Fetching(三)
一看就会的Next.js App Router版 -- Data Fetching
370 0
|
缓存 前端开发 数据库
一看就会的Next.js App Router版 -- Data Fetching(二)
一看就会的Next.js App Router版 -- Data Fetching
129 0
|
存储 缓存 前端开发
一看就会的Next.js App Router版 -- Data Fetching(一)
一看就会的Next.js App Router版 -- Data Fetching
531 0
|
SQL 存储 JavaScript
一看就会的Next.js App Router版 -- Routing(下)(三)
一看就会的Next.js App Router版 -- Routing
530 0