Skip to content

[BUG] ref used for scoping the useHotkeys breaks the tabbing behavior when assigned to conditionally rendered element #1313

@oleksandr-danylchenko

Description

@oleksandr-danylchenko

Issue

Using ref returned from useHotkeys on conditionally rendered element which is initially absent results in weird (and possibly unintended) behavior:

  • On initial render keydown event listener will be added to the document:
    Image
  • When the element becomes present, ref will update.
  • Listener will still be on the document but behave like it is added to the element.

As a result, all keydown events will be stopPropagationed and preventDefaulted when the focus is outside the element. Among other things, Tab navigation stops working, which is an accessibility concern.
Image
©️ @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:

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:

Reproduction

Steps to reproduce the behavior:

  1. Create a conditionally rendered element.
  2. Assign the ref returned from the useHotkeys to that element.
  3. Toggle the element "in".
  4. Observe that the Tab/Enter key became unresponsive.

Codesandbox example

Link - https://codesandbox.io/p/sandbox/gxm4gk

CleanShot.2026-02-04.at.12.50.11.mp4

Expected behavior

  1. The hoot ref should be re-attached to the conditionally rendered element instead of getting stuck attached to the document.
  2. The documentation should match the behavior where the "ref callback" is returned instead of the "plain mutable ref".

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions