NextUI中的服务器组件支持:RSC与客户端组件混用
什么是React服务器组件(RSC)
React服务器组件(React Server Components,简称RSC)是React 18引入的新特性,它允许组件在服务器端渲染,而无需将JavaScript发送到客户端。这可以显著减小应用的bundle体积,提高初始加载性能,并改善SEO。
在NextUI中,我们提供了对RSC的完整支持,使开发者能够无缝地混合使用服务器组件和客户端组件,构建高性能的现代React应用。
NextUI的RSC架构
NextUI通过@heroui/system-rsc包提供对React服务器组件的支持。这个内部工具包为服务器组件提供了必要的系统功能,同时确保与客户端组件的兼容性。
RSC包结构
RSC支持主要通过以下包实现:
- 系统RSC包:packages/core/system-rsc/
- React核心包:packages/core/react/
安装RSC支持
要在项目中使用NextUI的RSC支持,只需安装@heroui/system-rsc包:
yarn add @heroui/system-rsc
# 或
npm i @heroui/system-rsc
注意:这是一个内部工具,不建议直接用于公共使用。开发者应该使用NextUI的主要入口点,如
@heroui/react。
服务器组件与客户端组件混用策略
NextUI采用了灵活的策略,允许开发者根据需要混合使用服务器组件和客户端组件。
1. 组件分类
NextUI将组件分为两类:
- 纯服务器组件:不包含任何客户端交互逻辑,可以直接在服务器端渲染
- 客户端组件:包含交互逻辑,需要在客户端 hydration
2. 客户端组件标记
所有包含客户端交互的组件都在其入口文件顶部添加了"use client"指令,例如在packages/core/react/src/index.ts中:
"use client";
export * from "@heroui/system";
export * from "@heroui/theme";
// ...其他导出
这个指令告诉React该组件及其导入的所有子组件都应该在客户端渲染。
3. 服务器组件导出
系统RSC包导出了可在服务器组件中安全使用的类型和工具函数:
export type {
As,
DOMElement,
DOMElements,
CapitalizedDOMElements,
DOMAttributes,
OmitCommonProps,
RightJoinProps,
MergeWithAs,
InternalForwardRefRenderFunction,
PropsOf,
Merge,
HTMLHeroUIProps,
PropGetter,
SharedSelection,
} from "./types";
export {
forwardRef,
toIterator,
mapPropsVariants,
mapPropsVariantsWithCommon,
isHeroUIEl,
} from "./utils";
实际应用示例
1. 服务器组件中使用NextUI
以下是一个使用NextUI组件的服务器组件示例:
// 这是一个服务器组件,没有"use client"指令
import { Button } from "@heroui/react";
export default function ServerComponent() {
return (
<div>
<h1>服务器渲染的页面</h1>
{/* Button组件内部有"use client"指令,会自动在客户端渲染 */}
<Button>点击我(客户端组件)</Button>
</div>
);
}
2. 布局组件中的混合使用
NextUI文档中的布局组件展示了如何在实际项目中混合使用服务器和客户端组件:
// [apps/docs/app/docs/layout.tsx](https://link.gitcode.com/i/14ea7e8b376c7174d7ac34b0171e36ae)
import { Image } from "@heroui/react";
import manifest from "@/config/routes.json";
import { DocsSidebar } from "@/components/docs/sidebar";
import { ScriptProviders } from "@/components/scripts/script-providers";
interface DocsLayoutProps {
children: React.ReactNode;
}
export default function DocsLayout({ children }: DocsLayoutProps) {
return (
<>
<main className="relative container mx-auto max-w-8xl z-10 px-6 min-h-[calc(100vh_-_64px_-_108px)] mb-12 grow">
<div className="grid grid-cols-12">
<div className="hidden overflow-visible relative z-10 lg:block lg:col-span-2 mt-8 pr-4">
<DocsSidebar routes={manifest.routes} />
</div>
{children}
</div>
</main>
{/* 其他内容 */}
<ScriptProviders />
</>
);
}
3. 客户端组件包装器
为了在服务器组件树中嵌入客户端组件,NextUI提供了Providers组件,如apps/docs/app/providers.tsx所示:
"use client";
import { HeroUIProvider } from "@heroui/react";
import { ThemeProvider as NextThemesProvider } from "next-themes";
export function Providers({ children, themeProps }) {
const router = useRouter();
return (
<ProviderWrapper>
<HeroUIProvider navigate={router.push}>
<NextThemesProvider {...themeProps}>{children}</NextThemesProvider>
</HeroUIProvider>
</ProviderWrapper>
);
}
这个客户端组件包装了整个应用,并提供了主题和导航功能。
最佳实践与注意事项
1. 合理划分组件边界
- 将纯展示性内容放在服务器组件中
- 将交互逻辑封装在客户端组件中
- 尽量将客户端组件放在组件树的叶子节点
2. 避免服务器组件中的浏览器API
服务器组件中不能使用浏览器API,如window、document等。如果需要使用这些API,应该将相关逻辑移到客户端组件中。
3. 注意状态管理
服务器组件不能使用React的状态钩子(如useState、useEffect),这些应该只在客户端组件中使用。
4. 优化数据获取
利用服务器组件的优势,在服务器端获取数据,减少客户端请求:
// 服务器组件中获取数据
async function ProductPage({ params }) {
const product = await fetchProduct(params.id);
return (
<div>
<h1>{product.name}</h1>
<ClientAddToCartButton productId={product.id} />
</div>
);
}
总结
NextUI通过@heroui/system-rsc包和精心设计的组件结构,为React服务器组件提供了全面支持。这种架构允许开发者:
- 充分利用RSC的性能优势,减小客户端bundle体积
- 灵活混合使用服务器组件和客户端组件
- 保持一致的开发体验和组件API
随着React生态系统的不断发展,NextUI将继续优化其RSC支持,为开发者提供更好的工具和体验。
要开始使用NextUI构建支持RSC的应用,只需从https://link.gitcode.com/i/606d00e43ee93524788e973ef56630f7克隆仓库,并按照文档开始开发。
本文档内容基于NextUI的当前实现,随着版本迭代可能会有变化。建议查阅最新的官方文档以获取最新信息。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



