Headless UI Disclosure 渲染道具错误:“函数作为客户端组件的子组件无效。”

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

我尝试使用 Tailwind 组件库中的导航栏,但我使用 Headless UI 的方式有问题。我正在关注 https://headlessui.com/react/disclosure,但我不知道如何实现 render prop 示例。我有一个 Next.js 项目和两个主文件,page.tsx 和 Example.tsx

//src/app/page.tsx
import React from "react";
import Example from "@/components/ui/Example";

export default function Home() {
  return (
    <main>
      <Example />
    </main>
  );
}
//src/ui/Example.tsx
import { Disclosure, DisclosureButton, DisclosurePanel } from "@headlessui/react";
import { ChevronDownIcon } from "@heroicons/react/20/solid";
import clsx from "clsx";

export default function Example() {
  return (
    <Disclosure>
      {({ open }) => (
        <>
          <DisclosureButton className="flex items-center gap-2">
            Do you offer technical support?
            <ChevronDownIcon className={clsx("w-5", open && "rotate-180")} />
          </DisclosureButton>
          <DisclosurePanel>No</DisclosurePanel>
        </>
      )}
    </Disclosure>
  );
}

我得到:

错误:函数作为客户端组件的子组件无效。如果您返回子级而不是从渲染返回,则可能会发生这种情况。或者也许您打算调用此函数而不是返回它。 <... children={function children}>

问题似乎出在

{({open}) => ...}
函数上。我需要将它变成一个有效的组件,但我不知道如何做。

next.js web-frontend tailwind-ui headless-ui
1个回答
0
投票

在 NextJS 中,所有组件默认都是 服务器组件

Disclosure需要是客户端组件,因为它必须是交互式的(显示/隐藏)并且可能使用一些钩子(仅在客户端组件中可用)

// add "use client" directive
"use client"

import { Disclosure, DisclosureButton, DisclosurePanel } from "@headlessui/react";
import { ChevronDownIcon } from "@heroicons/react/20/solid";
import clsx from "clsx";

export default function Example() {
  return (
    <Disclosure>
      {({ open }) => (
        <>
          <DisclosureButton className="flex items-center gap-2">
            Do you offer technical support?
            <ChevronDownIcon className={clsx("w-5", open && "rotate-180")} />
          </DisclosureButton>
          <DisclosurePanel>No</DisclosurePanel>
        </>
      )}
    </Disclosure>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.