KASHIMURA Blog

Webサービス開発のこと、個人的なことを書いているブログ

PopoverTriggerの子要素に自作コンポーネントを使う場合はforwardRefを使う(ChakraUI)

ChakraUI (v2.4.1)のポップオーバーを使ってたとき、トリガーになるボタンを独自のコンポーネントにしたら動かなくなったので、原因と対応内容を備忘録として残す。

🙆‍♂️ まず、ChakraUIのポップオーバーは以下のように実装する。
PopoverTriggerで囲んだButtonやBoxがクリックされた時、PopoverContentが表示されるような仕様。

<Popover>
  <PopoverTrigger>
    <Button>ボタン</Button>
  </PopoverTrigger>
  <PopoverContent>
    ...
  </PopoverContent>
</Popover>

🙅‍♂️ ただ、以下の実装だと動かない。
PopoverTriggerで囲っている要素が独自で作成したコンポーネントの場合はクリックしても何も起きなくなった...

export const HogeButton: FC = ({children}) => (
  <Button>
    {children}
  <Button>
)
<Popover>
  <PopoverTrigger>
    <HogeButton>ボタン</HogeButton>  // これだと発火しない
  </PopoverTrigger>
  <PopoverContent>
    ...
  </PopoverContent>
</Popover>

これはなぜかというと、Popoverがrefを使っているためっぽい。

じゃ、どうするかというとforwardRefを使ってrefを扱えるようにしてあげる。
HogeButtonを↓こう書き換える。

import { ButtonProps, forwardRef } from "@chakra-ui/react";

export const HogeButton = forwardRef<ButtonProps, "button">((props, ref)) => (
  <Button ref={ref} {...props} />
)

これでPopoverTriggerの子要素にしても動くようになった 👍

参考:Popover - Chakra UI