React Server Components 出来以后,很多团队重新审视样式方案,不是因为 CSS-in-JS 突然没用了,而是因为它原本依赖的运行时注入、客户端状态和组件边界,和 RSC 的执行方式并不总是天然兼容。
所以问题不再是“CSS-in-JS 好不好”,而是“在 RSC 约束下,哪些方案还能稳定工作”。
先理解 RSC 为什么会改变样式方案判断
RSC 的核心价值,是把更多组件计算前移到服务端,减少客户端 JavaScript 负担。但这也意味着很多过去默认存在的客户端上下文不再稳定。
对 CSS-in-JS 来说,风险主要在三点:
- 运行时样式注入依赖客户端执行
- 样式收集需要明确的服务端边界
- Server Component 和 Client Component 混用时,样式 ownership 更复杂
如果团队忽略这些边界,就会遇到样式闪烁、重复注入或 hydration 不一致。
不同 CSS-in-JS 路线的关键差异在“运行时占比”
在 RSC 语境里,样式方案可以大致分成三类:
- 运行时注入型:灵活,但对客户端和 SSR 协调要求更高
- 编译时提取型:更接近静态 CSS,通常更容易适应 RSC
- 混合型:保留部分动态能力,同时尽量减少运行时成本
因此选型时要优先判断的,不是 API 喜好,而是项目到底需要多少运行时动态样式。
更稳的做法是把动态样式控制在清晰边界内
许多样式问题不是来自 CSS-in-JS 本身,而是动态能力被滥用。对 RSC 项目来说,更好的策略往往是:
- 基础布局和静态视觉走可预生成方案
- 少量主题、状态和密度变化留给客户端
- 把高频动态样式集中在明确的 Client Component 边界里
'use client'
import { css } from '@emotion/css'
export function ThemeBadge({ active }: { active: boolean }) {
return (
<span
className={css({
padding: '4px 8px',
borderRadius: 999,
backgroundColor: active ? '#111827' : '#e5e7eb',
color: active ? '#fff' : '#111827',
})}
>
{active ? 'Active' : 'Idle'}
</span>
)
}
迁移时优先避免“大一统重写”
如果项目已经大量使用 CSS-in-JS,不建议因为接入 RSC 就一次性重写为另一种方案。更可控的路径通常是:
- 先盘点哪些样式必须依赖运行时
- 新增 Server Component 优先采用更稳的静态方案
- 旧 Client Component 维持现有方案并逐步收边界
- 通过基准测试确认样式注入、首屏和 hydration 风险
这种渐进方式比“全面推倒重来”更适合真实团队。
一个常见失败案例:团队只看趋势选型,不看项目边界
这类问题通常表现为:
- 因为 RSC 流行就全量改造样式栈
- 没盘点动态样式真实需求
- 没给 Server/Client 边界设规则
- 迁移后样式心智模型更复杂
最终不是技术选错,而是迁移策略没有围绕项目实际边界展开。
一份可直接复用的检查清单
- 团队是否先理解了 RSC 对样式运行时的约束
- 选型是否基于运行时占比,而不是单纯 API 偏好
- 动态样式是否被限制在明确的 Client Component 边界内
- 迁移方案是否采取渐进式,而不是大一统重写
- 是否用真实指标验证了首屏、注入和 hydration 风险
总结
CSS-in-JS 在 RSC 中并不是不能用,而是必须更清楚地理解边界。只要先判断动态样式需求、明确 Server/Client 职责,再采用渐进迁移策略,样式体系依然可以在 RSC 架构里稳定工作。
进一步阅读:


