By Steven guo1 min read210 words

Next.js 服务端组件

Technology
nodejs
react

Next.js 客户端组件和服务端组件的区别、服务端组件和服务端渲染(SSR)的区别、服务端组件能否替代服务端渲染、GraphQL

Next.js 介绍

Next.js is a framework for building web applications.

你可以使用React组件构建用户界面,Next.js提供了额外的结构、特性、优化。

FeatureDescription
路由基于文件系统的路由器构建在服务器组件之上,支持布局、嵌套路由、加载状态、错误处理等。
渲染使用客户端和服务器组件进行客户端和服务器端渲染。使用 Next.js 在服务器上进一步优化静态和动态渲染。在 Edge 和 Node.js 运行时上进行流式传输。
数据获取通过 React 组件中的异步/等待支持以及
fetch()
与 React 和 Web 平台保持一致的 API,简化了数据获取。
样式CSS Modules, Tailwind CSS, and CSS-in-JS
优化图像、字体和脚本优化,以改善应用程序的核心网络生命和用户体验。
TypeScript改进了对 TypeScript 的支持,提供更好的类型检查和更高效的编译,以及自定义 TypeScript 插件和类型检查器。
API 参考..

客户端组件和服务端组件的区别

客户端组件就是我们日常开发中使用的React组件(类组件和函数式组件),它是由客户端(浏览器)渲染的

服务端组件是一种新型组件,在React18之后新加入的,这种类型的组件会在服务端完成渲染再发送到客户端。

服务端组件和服务端渲染(SSR)的区别

在React中,传统的服务端渲染仅生成页面的初始HTML快照,仍然需要下载所有的JS代码,才能使网页具有交互性。

而服务端组件是在服务端渲染完通过流的方式以某种协议传输给客户端,客户端无需重新渲染整个页面,只会渲染树中组件所在的节点。

Untitled.png

服务端组件能否替代服务端渲染、GraphQL

实际上服务端组件和服务端渲染是互补的,服务端渲染解决的首屏加载的问题,而服务端组件解决的是服务端渲染不能很好支持的状态丢失,共享数据等问题。而服务端组件也可以很好的和GraphQL结合,在获取数据时使用GraphQL获取数据也是没有问题的。

服务端组件的特点

  1. 服务端组件不会对包大小产生影响,甚至可能减少前端包的体积
  2. 可以直接访问后端资源
  3. 客户端代码自动分割
  4. 统一范式,共享组件,根据应用程序灵活选用你需要的组件

服务端组件不能有任何交互行为(例如:不能使用 useState(),useEffect())。但是你可以通过在服务端组件内部引入客户端组件(客户端组件是允许存在交互行为的)的方式来解决这个问题.

什么时候使用服务端组件、客户端组件

What do you need to do?Server ComponentClient Component
获取数据
直接访问后端资源
在服务器上保留敏感信息(access tokens, API keys, etc)
大的依赖包,减小客户端size
添加交互性和事件侦听器(
onClick()
onChange()
等)
使用状态和生命周期效果(
useState()
useReducer()
useEffect()
等)
使用仅限浏览器的 API
使用依赖于状态、效果或仅限浏览器的 API 的自定义Hook
使用React类组件

在客户端组件中,不支持将服务端组件直接导入到客户端组件,但是可以通过客户端组件的children属性来传递服务端组件。

服务端组件嵌套客户端组件时,属性只能传递可被JSON序列化的值,函数,日期都是不能直接传递给客户端组件的。

服务端组件中使用的一些环境变量,在客户端组件中是访问不到的。

server-only
 这个包可以检测仅服务端使用的代码导入到客户端组件时会在构建时候报错,相应的还有个
client-only

客户端组件中可以使用上下文(next的根组件一般为服务端组件,需要使用客户端组件包装一层来提供类似全局上下文的效果)

服务端组件渲染使用上下文的客户端组件(一些第三方库可能并没有加**

'
use client
** ,需要我们手动包一层)

在服务器组件之间共享数据(例如共享数据库连接)

在服务器组件之间共享获取请求(fetch经过优化,有缓存机制)

混合使用客户端和服务器组件

当你混合使用客户端和服务器组件时,应当将 UI 视为组件树。从根布局开始(它是一个服务器组件),你可以通过添加 "use client" 指令在客户端渲染某些子树。

虽然在这些客户端子树中仍然可以嵌套服务器组件或调用服务器操作,但仍有一些事情需要注意:

  • 如果需要在客户端访问服务器上的数据或资源,客户端需要向服务器发出新的请求。
  • 当向服务器发出新请求时,首先渲染所有服务器组件,在客户端上,React 会使用 RSC Payload 将服务器组件和客户端组件调和成一棵树。
  • 由于客户端组件是在服务器组件之后呈现的,因此不能将服务器组件导入到客户端组件中。正确的方式应该是:将服务器组件作为属性传递给客户端组件(如:children),这种方式允许你在客户端组件中使用来自服务器组件的数据或内容,而不必再次请求服务器。