Next.js中如何从客户端组件导入对象到服务端组件?
Next.js 13 App Router:客户端组件导出对象到服务端组件变为函数的问题及解决方法
原因分析
当文件顶部添加'use client'标记后,Next.js会将整个文件视为客户端组件模块。服务端组件导入这类模块时,Next.js会对模块做特殊包装:整个模块会被转换成客户端组件的懒加载引用(本质是一个函数),模块内所有导出内容都会被包裹在这个函数中。因此,服务端组件中拿到的exportedObject并非你定义的原始对象,而是这个包装函数,自然无法直接访问对象属性。
解决方法(无需将服务端组件转为客户端组件)
方法1:将共享对象移至独立的无标记文件
把不需要客户端环境的共享值(比如静态对象)放在一个既无'use client'也无'use server'标记的普通JS/TS文件中,服务端和客户端组件都能直接导入并获取原始值。
示例代码:
// shared.js // 无任何特殊标记,属于通用模块 export const exportedObject = { foo: 'bar' };
客户端组件修改:
// ClientComponent.js 'use client'; import { exportedObject } from './shared'; export default function ClientComponent() { return <div>RCC</div>; }
服务端组件修改:
// ServerComponent.js import { exportedObject } from './shared'; console.log(exportedObject); // 输出:{ foo: 'bar' } export default function ServerComponent() { console.log(exportedObject); return <div>RSC</div>; }
方法2:若对象依赖客户端环境,通过props传递(动态场景)
如果exportedObject必须在客户端组件中定义(比如依赖浏览器API或客户端状态),可以通过客户端组件向服务端组件传递props的方式传递数据。这种方式仅适用于客户端组件已渲染、数据需要动态传递的场景:
// ClientComponent.js 'use client'; import ServerComponent from './ServerComponent'; const exportedObject = { foo: 'bar' }; export default function ClientComponent() { return <ServerComponent sharedObject={exportedObject} />; }
// ServerComponent.js export default function ServerComponent({ sharedObject }) { console.log(sharedObject); // 输出:{ foo: 'bar' } return <div>RSC</div>; }
注意:服务端组件首次渲染时无法获取客户端传递的props,只有客户端组件完成渲染后,服务端组件才会接收到这些值并重新渲染(依赖React状态机制)。
内容的提问来源于stack exchange,提问作者Magnus
相关产品推荐
相关产品推荐

