我有一个可能很常见的情况,客户端组件(CC)使用 useState 钩子有条件地渲染服务器组件(SC)。 CC 会将其导入的任何组件转换为 CC,在本例中这是不需要的,因为它们不会按应有的方式工作。
我想象在这些情况下有一个可以遵循的良好模式。 你会如何处理这个简单的案例?是否应该将 SC 改为 CC? MyPage 实际上应该是一个 SC,并以某种方式使用更简单的 CC 来处理选项卡选择吗?
我的页面:
'use client'
export default function MyPage() {
const [activeTab, setActiveTab] = useState('A')
return (
<div>
<div>
<Button
onClick={() => setActiveTab('A')}
>
Render A
</Button>
<Button
onClick={() => setActiveTab('B')}
>
Render B
</Button>
</div>
<div>
{activeTab === 'A' && <ComponentA />}
{activeTab === 'B' && <ComponentB />}
</div>
</div>
)
}
成分A:
'use server'
export default async function ComponentA() {
const data = await getDataForA()
return (
<div>
{data.map((item) => (
<span key={item.id}>{item}</span>
))}
</div>
)
}
组件B:
'use server'
export default async function ComponentB() {
const data = await getDataForB()
return (
<div>
{data.map((item) => (
<span key={item.id}>{item}</span>
))}
</div>
)
}
'use client'
import { useState } from 'react'
export default function ClientComponent({
children,
}: {
children: React.ReactNode
}) {
const [count, setCount] = useState(0)
return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>
{children}
</>
)
}
文档说:
然后:
<ClientComponent>
不知道孩子最终会被填满 由服务器组件的结果输入。唯一的责任<ClientComponent>
是决定孩子们最终会去哪里 已放置。
// This pattern works:
// You can pass a Server Component as a child or prop of a
// Client Component.
import ClientComponent from './client-component'
import ServerComponent from './server-component'
// Pages in Next.js are Server Components by default
export default function Page() {
return (
<ClientComponent>
<ServerComponent />
</ClientComponent>
)
}
尽管在您的客户端组件中,您可能需要使用 children
之外的一些道具,如
serverCompElementA
和
serverCompElementB
,以轻松访问组件:
// This pattern works:
// You can pass a Server Component as a child or prop of a
// Client Component.
import ClientComponent from './client-component'
import ServerComponentA from './server-componentA'
import ServerComponentB from './server-componentB'
// Pages in Next.js are Server Components by default
export default function Page() {
return (
<ClientComponent serverCompElementA={<ServerComponentA />} serverCompElementB={<ServerComponentB />}/>
)
}
最后,虽然文档没有专门提供这样的示例,并且我还没有测试过,但您应该能够根据需要在客户端组件中有条件地渲染 serverCompElementA
和
serverCompElementB
。