服务端组件是什么?

截至目前,我们对 React 组件的了解只是客户端组件,仅此而已。

然而,React 团队正在试验一个新的想法,那就是将 React 组件区分为两个类型:客户端组件 和 服务端组件。该提案的开头就是使用不同的文件扩展名(.client.js 和.server.js)来区分它们。然而,客户端组件和服务端组件到底是怎么定义的?

首先,客户端组件指的就是现在我们日常开发中使用的 React 组件。

其次是服务端组件,从某种意义上来说它是一个新型组件,该类型的组件会在服务端完成渲染后,再发送到客户端。

服务端组件哪些优势?

乍一看,服务端组件 类似于 服务端渲染(SSR),实际上,服务端组件的很多优势和服务端渲染也是很类似:

提供了直接访问服务端资源(如:数据库、文件系统、内部的微服务等)的可能,因此开发起来会更容易。

避免了不必要的客户端和服务端之间的交互,因此性能更快。

允许一些类库可以直接运行在服务端,因此减小了客户端包文件的大小。

除此之外,服务端组件还给开发过程带来了更好的体验,特别是在代码切割上:

自动代码切割(例如:为了让客户端实现按需加载,需要将代码切割成一个个的小包),目前为了实现这个功能,React 开发人员需要手动实现如下代码:

未来,服务端组件 会自动处理,这就意味着,我们无需特殊代码处理就可以实现此功能:

然而,要想真正体会到 服务端组件 的强大优势,必须将其与服务端渲染(SSR)进行更细致的比对。

服务端组件和 SSR 有哪些不同

在使用 SSR 时,你需要先在服务端完成 HTML 的渲染,然后再将该 HTML 发送到客户端。然后此过程只会发生在页面的初次访问时(也就是初始化加载的时候)。至此之后,你的 React 应用在数据更新展示等行为表现上和常规的 React 应用没有任何区别。在展示更新之后的数据时,都是要么从客户端发送一个网络请求,要么页面整体刷新,但不管采用哪种方式,都会导致组件的二次渲染和状态丢失,从而影响性能和客户体验。

相对而言,在使用服务端组件时,你的组件在服务端完成渲染,然后通过自定义的协议发送到客户端(如下图)。React 拿到数据时,将新的 UI 整体的合并到客户端 UI 树里面,此过程不会对客户端其他状态产生影响。此过程可以无限次数的执行。React 通过整体 UI 模块更新的方式,达到保持客户端状态的目的,极大的增强了用户体验。

要了解更多的细节可以参考 Dan Abramov 在推特上的 这条回复,或者阅读来着 React 数据团队的 Lauren Tan 在 Twwiter 的 帖子,或者访问 Mehul Mohan 发布在 freeCodeCamp 上的 这篇文章

注意事项

由于服务端组件是静态的、服务端渲染的,因此相对于客户端组件,不可避免的会有些使用限制。

首先,服务端组件不能有任何交互行为(例如:不能使用 useState(),useEffect())。但是你可以通过在服务端组件内部引入客户端组件(客户端组件是允许存在交互行为的)的方式来解决这个问题。例如下面的示例代码就做到了两者兼顾:

其次,由于服务端组件是在服务端完成渲染后通过网络传输给到客户端,因此服务端组件传输 props 到客户端组件的时候,props 必须被序列化(意味着:可传输的数据只能是字符串、JSON 对象或者 JSX,不能传输 JavaScript 函数)。