Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useDisplayOrder: clears incorrect #6000

Closed
Manizuca opened this issue Feb 18, 2024 · 6 comments · Fixed by #6010 or #6012
Closed

useDisplayOrder: clears incorrect #6000

Manizuca opened this issue Feb 18, 2024 · 6 comments · Fixed by #6010 or #6012
Assignees
Labels
Type: Bug Issue contains a defect related to a specific component.
Milestone

Comments

@Manizuca
Copy link

Manizuca commented Feb 18, 2024

Describe the bug

The useDisplayOrder hooks clears out an incorrect id when unmounting, so very simple Dialogs configurations throw "Unexpected: global esc key listener with priority [300, x] already exists." errors", even if not using the 'closeOnEscape' option (if they are not destroyed in the reverse order they become visible).

delete groupToDisplayedElements[group][newDisplayOrder];

Here, the information is deleted taking the generated displayOrder as an index, but that will always be off by 1.

In the attached example, te following happens in this order:

  • Dialog "one" is created visible, is asigned displayOrder 1.
  • Dialog "two" becomes visible, is asigned displayOrder 2.
  • Dialog "one" is hidden. Because of this bug, the information for Dialog "two" is removed, as the value of groupToDisplayedElements[group] is [dialogOne, dialogTwo], and deleted the value with index 1.
  • Dialog "three" becomes visible, is asigned displayOrder 2.

Finally, because there are two visible Dialogs with displayOrder 2, the application crashes.

The fix should be pretty trivial, just delete the item with index newDisplayOrder - 1. Also, i think the global Esc handler should not be added if closeOnEscape is false.

Reproducer

https://stackblitz.com/edit/vitejs-vite-e88fmg

PrimeReact version

10.5.1

React version

17.x

Language

ES6

Build / Runtime

Create React App (CRA)

Browser(s)

No response

Steps to reproduce the behavior

Just load the page, and look for the "Unexpected: global esc key listener with priority [300, 2] already exists." error.

Expected behavior

Should not crash.

@Manizuca Manizuca added the Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible label Feb 18, 2024
@melloware melloware added Type: Bug Issue contains a defect related to a specific component. and removed Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible labels Feb 19, 2024
@melloware melloware self-assigned this Feb 19, 2024
@melloware melloware added this to the 10.5.2 milestone Feb 19, 2024
melloware added a commit to melloware/primereact that referenced this issue Feb 19, 2024
@melloware
Copy link
Member

Thanks for the report. I improved closeOnEscape logic on a few components including this one.

@Manizuca
Copy link
Author

Thanks @melloware , this fixes the problem for me. I think the useDisplayOrder code should be fixed too, since it could still happen when closeOnEscape is true.

@melloware
Copy link
Member

well what is weird is I can't reproduce your error with the showcase. Now showcase is Next.Js not sure if that makes a difference or not. Want to suggest a PR?

@Manizuca
Copy link
Author

Changing the closeOnEscape value to true con the reproducer throws the error for me for that case, doesn't it happen for you?

I think it should work by changing
delete groupToDisplayedElements[group][newDisplayOrder];
to
delete groupToDisplayedElements[group][newDisplayOrder - 1];

I could create a PR later today if you want.

@melloware
Copy link
Member

let me try that. And no in using the showcase i can't get it to error!

@melloware
Copy link
Member

melloware commented Feb 19, 2024

@Manizuca can you check out my new PR it refactors how that is done...

  1. Removed the unnecessary check if (!(group in groupToDisplayedElements)) since we're checking if groupToDisplayedElements[group] exists directly.
  2. Simplified the calculation of newDisplayOrder by using the push method, which returns the new length of the array.
  3. Removed the deletion of elements by index and replaced it with finding the index of the element using indexOf and then removing it using splice.
  4. Removed the cleanup logic to reduce the length of the array since it seems unnecessary considering we are setting setDisplayOrder(undefined).

This version should be cleaner and more concise while maintaining the same functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Issue contains a defect related to a specific component.
Projects
None yet
2 participants