原文链接:CSS in React Server Components

1. 服务器组件

  1. 用户访问我们的网络应用
  2. Node.js 接收请求,并在无窗口服务器环境中运行 React. 它会渲染我们的应用程序,并生成一个包含所有初始用户界面的完整 HTML文档。
  3. 当该 Html 文档加载到用户设备上时,React 将重新渲染所有相同的组件,重复服务器上的工作。不过,React 不会生成新的 HTML 元素,而是采用服务器生成的 HTML元素。也就是所谓的 “水合”

服务器组件限制

例如 useState ,当状态变量发生变化时,组件会重新渲染,但服务器组件无法重新渲染,它们的代码升值从未发送到浏览器,因此React无法知道如何处理状态变化,从React的角度来看,服务器组件生成的任何标记都是固定不变的,客户端无法修改。

服务器组件并不是真正的React组件,至少不是我们传统意义上理解的React组件。它们更像是 PHP模板,由服务器渲染以创建原始HTML。真正的创新在于服务器组件和客户端组件可以共存于一个应用程序中。

2. 客户端组件

客户端组件是同时运行于服务器和客户端的组件,在传统(RSC之前)React中编写的每个React组件都是客户端组件,这是一个旧事物的名称。

use client 指令创建了一个“客户端边界”,该文件中的所有组件以及任何导入的组件都将作为客户端组件渲染,首先在服务器上运行,然后再在客户端上运行

CSS-in-JS 在 RSC中存在的问题

不兼容style-compoents是为在浏览器中运行而设计的,而服务器组件从不接触浏览器。在内部,styled-components 大量使用了 useContext 钩子,它的目的是与React生命周期绑定,但服务器组件并没有React生命周期。因此,如果我们想在这个全新的React服务器组件中使用 styled-components ,那么每个使用了 styled-components 组件的React组件都需要成为客户端组件

解决方案

Linaria

使用方式于styled-componments 一样,但是处理方式不同,Linaria 在编译阶段处理CSS,并将所有的样式移入 CSS Modules 中。它会先将类似于styled-components 的代码编译成 CSS Module,然后再将CSS Module 处理为纯CSS,这些行为都在编译时完成

Panda CSS

与 Linaria 不同的是,Panda CSS 会将类似 styled-components 的代码转换为 CSS Utils 类,该文件将加载到React应用程序中的每个路由上。

Pigment CSS

Pigment css 在编译时运行,它采用与 Linaria 相同的策略,即编译为CSS模块。Next.js 和 Vite 都有对应的插件。它使用了一种名为 Wyw-in-JS 的底层工具。这个工具是从 Linaria 代码库中发展出来的,它隔离了“编译为CSS Module”的业务逻辑,并将其通用化,这样像 Pigment CSS的库就可以在此基础上构建自己的 API。

很多人把RSC和SSR搞混了,服务器端渲染的工作方式与以往完全相同,不受任何应用。如果你迁移到 Next和APP Router 或者其他RSC实现,你的应用程序速度应该不会变慢,事实上它可能会变得更块,从性能角度来说,RSC和零运行时CSS库的主要优势在于 [TTI],这是用户界面显示给用户与用户界面完全交互之间的延迟时间。如果忽略了这一点,就会产生糟糕的用户体验。用户会开始点击一些东西,希望它们能起作用,但由于应用程序仍在水合过程中,所以什么都没有发生。