-
Notifications
You must be signed in to change notification settings - Fork 159
[BUG] ref used for scoping the useHotkeys breaks the tabbing behavior when assigned to conditionally rendered element #1313
Description
Issue
Using
refreturned fromuseHotkeyson conditionally rendered element which is initially absent results in weird (and possibly unintended) behavior:
- On initial render
keydownevent listener will be added to thedocument:
- When the element becomes present,
refwill update.- Listener will still be on the
documentbut behave like it is added to the element.As a result, all
keydownevents will bestopPropagationed andpreventDefaulted when the focus is outside the element. Among other things, Tab navigation stops working, which is an accessibility concern.
©️ @chernetsov0
Context
This issue is a revival of the related @chernetsov0's issue: #1198. It got resolved previously with the PR from @zeorin: #1132. Unfortunately, the fix got lost in the latest 5th major version bump!
The documentation still states that the useHotkeys returns the ref callback:
react-hotkeys-hook/packages/documentation/docs/documentation/useHotkeys/scoping-hotkeys.mdx
Lines 42 to 46 in f2006c7
| Everytime we press down the `c` key, both component trigger the callback. But how can we separate those two components | |
| and their assigned hotkeys? The answer is [`Refs`](https://react.dev/learn/manipulating-the-dom-with-refs). `useHotkeys` | |
| returns a [React ref callback function](https://react.dev/reference/react-dom/components/common#ref-callback) that we | |
| can attach to any component that takes a ref. This way we can tell the hook which element should receive the users focus | |
| before it triggers its callback. |
However, now it returns a plain mutable ref:
| const ref = useRef<T>(null) |
| return ref |
Reproduction
Steps to reproduce the behavior:
- Create a conditionally rendered element.
- Assign the
refreturned from theuseHotkeysto that element. - Toggle the element "in".
- Observe that the
Tab/Enterkey became unresponsive.
Codesandbox example
Link - https://codesandbox.io/p/sandbox/gxm4gk
CleanShot.2026-02-04.at.12.50.11.mp4
Expected behavior
- The hoot
refshould be re-attached to the conditionally rendered element instead of getting stuck attached to thedocument. - The documentation should match the behavior where the "ref callback" is returned instead of the "plain mutable ref".
