我正在使用Next.JS 13.4.19和新的app
文件夹来启用React服务器组件,并在尝试使用客户端子组件时遇到问题(即<ClientComponent.SubComponent \>
)在服务器组件中。ClientTest.jsx
是一个附加了子组件的客户端组件(假设这是一个客户端组件)
'use client'
export default function ClientTest() {
return <div>ClientTest</div>
}
ClientTest.Item = function ClientTestItem() {
return <div>ClientTest.Item</div>
}
page.jsx
是一个React服务器组件(允许访问数据库或文件系统)
import ClientTest from './ClientTest'
export default function Page() {
// ClientTest.Item is undefined, and the following line errors with:
// Unsupported Server Component type: undefined
return (
<ClientTest.Item />
);
}
似乎主要组件<ClientTest />
工作正常,但附加的<ClientTest.Item />
是未定义的:(
https://codesandbox.io/p/sandbox/currying-grass-wsvtn4?file=/app/page.tsx
可能的解决方法是通过制作另一个 Package 器客户端组件来简单地避免服务器组件中的子组件(在客户端组件中导入ClientTest.Item可以正常工作),但我更希望通过一些神奇的webpack配置来解决这个问题。或者可能是next.js中的一个bug?
供记录在案;在server组件中导入server子组件可以正常工作,在client组件中导入client子组件也可以正常工作。
编辑:
我正在开发一个组件库,它使用了相当多的子组件模式,所以这对我来说是一个“按预期工作”的服务器组件设计部分,还是一个“当前实现限制”/bug,这有很大的区别。
如果这是一个 * 永久 * 的设计限制,我们可能需要重新考虑我们的整个命名方案和架构,以避免可怕的DX,但我还没有发现任何结论,这在React文档。
2条答案
按热度按时间rkue9o1l1#
你做的一切都是正确的,这就是Next.js的问题。我只是对这种行为做了一个宽泛的解释。请参见https://stackoverflow.com/a/77077564/9047572
TL:DR:您需要“use client”指令来使用仅限客户端的特性。一旦组件成为客户端,其嵌套组件也是客户端的。无法更改或拦截此行为。
flmtquvp2#
我已经为我的案例找到了一个更好的解决方案(作为库作者,他需要发布暴露给服务器组件的客户端子组件),并将其发布在这里,以防有人遇到同样的问题;
我可以在单独的文件中附加和重新导出子组件,而不是使用
use client
将子组件附加到组件文件中。使用index.js
文件,我可以保持消费者的导入路径相同,并且由于此文件没有'use client'指令,因此在导入到React服务器组件时会正确解析:ClientTest/ClientTest.jsx
ClientTest/ClientTest.Item.jsx
ClientTest/index.js
(注意此文件中没有'use client'
)page.jsx
与以前一样,但现在应该可以正常工作更新的codesandbox:
https://codesandbox.io/p/sandbox/eloquent-hooks-x3qgl8?file=/app/ClientTest/index.ts