允许在客户端组件中渲染服务器组件的模式

问题描述 投票:0回答:1

我有一个可能很常见的情况,客户端组件(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>
  )
}
reactjs next.js design-patterns react-hooks
1个回答
1
投票

文档上描述了类似的用例。这里:

'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

© www.soinside.com 2019 - 2024. All rights reserved.