You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js App Router:服务端组件传递客户端组件作为Props的疑问

问题:服务端组件传递客户端组件作为Props为何能正常运行?

我原本的理解是,从服务端组件传递给客户端组件的所有Props都必须是可序列化的,这意味着无法从服务端组件向客户端组件传递函数,尝试这么做时会收到预期的错误提示。但在下方示例中,服务端组件渲染了一个客户端组件,该客户端组件接收另一个客户端组件作为Props。我原以为这无法运行,因为组件本质是函数,是从服务端组件传递的。请问这是正常运行的bug,属于反模式,还是我存在理解误区?

示例代码

page.tsx(服务端组件)

import ClientComponent from "./ClientComponent";
import ClientCounterView from "./ClientCounterView";

export default function Home() {
  return (
    <ClientComponent CounterView={ClientCounterView}></ClientComponent>
  )
}

ClientComponent.tsx(客户端组件,服务端边界)

'use client'

import { useState } from 'react'

export default function ClientComponent({CounterView}: {CounterView: React.ComponentType}) {
    const [count, setCount] = useState(0)

    return (
        <div>
            <h1>Client Component</h1>
            <CounterView></CounterView>
        </div>
    )
}

ClientCounterView.tsx(客户端组件,移除'use client'会报错)

'use client'

export default function ClientCounterView() {
    return (
        <div>
            <h1>Client Counter View</h1>
        </div>
    )
}

解答

这既不是bug,也不属于反模式,是你对服务端组件与客户端组件交互逻辑的理解存在误区,核心原因如下:

  • 服务端并未传递组件函数本身:当服务端组件导入带'use client'标识的组件时,服务端不会执行该组件的代码,也不会将组件函数序列化发送给客户端。服务端只会向客户端传递一个组件引用标识(类似唯一ID),客户端拿到这个标识后,会在自己的环境中加载对应的客户端组件代码。
  • 组件引用是可序列化的:这种标识本质是字符串或轻量级的可序列化数据,完全符合服务端到客户端的props序列化要求,所以不会触发错误。
  • 对比普通函数的区别:如果尝试从服务端组件传递一个未标记'use client'的普通函数(比如服务端定义的工具函数),此时服务端会试图序列化这个函数,而函数本身不可序列化,就会触发预期的错误。但你示例中传递的是客户端组件,属于客户端环境的代码,服务端只是传递引用,并非函数本身。
  • 这种用法是合法的:传递客户端组件作为props是React Server Components(RSC)中完全支持的场景,常用于实现动态渲染、高阶组件、组件组合等需求,不属于反模式。

内容的提问来源于stack exchange,提问作者brad119

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 14:10:08