radix-ui / themes

Radix Themes is an open-source component library optimized for fast development, easy maintenance, and accessibility. Maintained by @workos.
https://radix-ui.com/themes
MIT License
5.46k stars 194 forks source link

Application completely freezes when trying to close dropdown-menu from another component with useState. #155

Open Jailawi opened 11 months ago

Jailawi commented 11 months ago

Problem

I'm using a dropdown-menu component with a select-option (button) when selected opens a dialog component. I would like the drop-menu to close when the dialog is closed. I've tried with

const [open, setOpenDropMenu] = useState(false);

Used in drop-menu like:

<DropdownMenu.Root open={open} onOpenChange={setOpenDropMenu}>

The setOpenDropMenu is sent in as a prop to the dialog component and is used when the dialog is closed like:

setOpenDropMenu(false);

This works, but not all the time. It sometimes freezes the whole application and no button or link becomes clickable unless the whole website is refreshed.

Could it be a race condition problem? How can I resolve this in the best manner?

vladmoroz commented 11 months ago

Could you create a CodeSandbox reproduction?

Jailawi commented 11 months ago

Could you create a CodeSandbox reproduction?

Created this: CodeSandbox

  1. Click on OpenDrop-down menu
  2. Click on Open Dialog
  3. Click on Cancel
  4. Repeat 1-3 until the application freezes and it won't be possible to click on OpenDrop-down menu (it usually happens within maximum 10 tries)
vladmoroz commented 11 months ago

Not sure why this happens, but either way it's the best way to expose a handler like onCancel and call the state setter in the dropdown component itself like so:

// In your dropdown menu component
<Dialog onCancel={() => setDropdownMenuOpen(false)} />

I checked this in your CodeSandbox and it resolves the issue you mentioned https://codesandbox.io/p/devbox/ecstatic-dawn-fmq9vq

Jailawi commented 11 months ago

I tried the same steps in the CodeSandBox you linked however, the issue remains where the app freezes after 10-20 tries.

henryobiaraije commented 5 months ago

Looks like this has not been fixed yet. Is there a workaround for this?

vladmoroz commented 5 months ago

@benoitgrelard do you have an idea for what's going on? Feels like I'm missing something obvious

joaom00 commented 5 months ago

It seems that when closing the dialog or dropdown menu it is not cleaning correctly and pointer-events: none remains in the body. you can use setOpen(false) in the onCloseAutoFocus callback in Dialog.Content but this will wait for the Dialog exit animation. Another alternative I believe using setTimeout(() => setOpen(false)) will fix it

Lexachoc commented 1 month ago

@joaom00 The setTimeout solves my problem when I try to close the dropdown menu after closing the dialog! Thanks!