📑

【MUI】Menuを閉じるとDialogも閉じてしまうときの対処法

2023/09/20に公開

MUIのMenuコンポーネントとDialogの組み合わせでハマったことと、解決した方法をシェアします。

ダイアログを開いたときにメニューを閉じるとダイアログも閉じてしまう

躓いたのはこの挙動で、以下のようにMenuItemとDialogをまとめていて、クリックするとダイアログが開く運用にしていました。

EditMenuItem.tsx
<>
  <MenuItem onClick={handleDialogOpen}>編集</MenuItem>
  <EditDialog/> // 内部でMUIのDialogコンポーネントを使用
</>

メニュー項目とダイアログをセットで固めればダイアログの操作元を管理しやすく、かつMenu側のコンポーネントが膨らまないためこの形式を採用していました。

しかし、のちに 「ダイアログを開いたときにメニューは閉じる」 という(ある種当たり前の)仕様を加える際に問題が発生。
この構造で、MenuItemのクリックをトリガーにしてダイアログを開く→Menuコンポーネントを閉じる操作を実装すると、メニューと同時にダイアログも閉じてしまいました。

MUIは内部でReactのPortalを使用していて、DOMとしては外部に飛ばしているはずなのですが、、、Menu>Dialogという構造が原因であると推察。

解決方法:DialogをMenuの外に出す

上記の仮定の下、次のように修正したところ、解決しました。

EditMenuItem.tsx
<MenuItem onClick={handleDialogOpen}>編集</MenuItem>

ちなみにメニューの開閉は公式ドキュメントを踏襲したアンカーの状態管理(をフック化したもの)です。

Menu.tsx
<>
  <Menu>
    <EditMenuItem />
  </Menu>
  <EditDialog/> // ダイアログをメニューの外に移動
</>

ダイアログをメニューの外に出すことで期待通りの動きが確認できました。
メニューの項目とダイアログが増えたら、ダイアログ部分を分割するなどして整理すれば保守もしやすくなるでしょうか。

Discussion