🐙

RadixUI の Trigger 内では、 onClick ではなく onPointerDown を使う

2024/06/19に公開

問題

RadixUI を使って開発していたところ、意図せぬ挙動に遭遇して困った。

簡略化したコードが以下の通り。ドロップダウンでフィルターを設定するようなUI。

<DropdownMenu.Root>
    <DropdownMenu.Trigger asChild>
        <button>
            <div>メニューを開く</div>
            <button
              onClick={(e) => {
                e.stopPropagation();
                clearFilter(); // メニューで設定したフィルター項目をクリアする
              }}
            ></div>
        </button>
      </DropdownMenu.Trigger>

      <DropdownMenu.Portal>
        <DropdownMenu.Content>
            {/* ここにフィルターを設定するUI */}
        </DropdownMenu.Content>
    </DropdownMenu.Portal>
</DropdownMenu.Root>

この clearFilter 関数が呼ばれなくて困った。

解決

結論から言うと、 onClickonPointerDown に差し替えたところ、意図通りの挙動を実現できた。

<DropdownMenu.Root>
    <DropdownMenu.Trigger asChild>
        <button>
            <div>メニューを開く</div>
            <button
              onPointerDown={(e) => {
                e.stopPropagation();
                clearFilter(); // メニューで設定したフィルター項目をクリアする
              }}
            ></div>
        </button>
      </DropdownMenu.Trigger>

      <DropdownMenu.Portal>
        <DropdownMenu.Content>
            {/* ここにフィルターを設定するUI */}
        </DropdownMenu.Content>
    </DropdownMenu.Portal>
</DropdownMenu.Root>

こちらがおそらく、今回の問題に関連する issue。
[Tabs] stopPropagate on child component of Trigger not working #1807

RadixUI は内部的に onPointerDown を使っているから、onClick ではなく onPointerDown を使ってね、ということを言っている。

Discussion