TanStack Hotkeys version
v0.10.0 (also v0.9.1)
Framework/Library version
React v19.2.5
Describe the bug and the steps to reproduce it
Two ways this bites:
A ref that's still null when the effect first runs never registers, even after it attaches:
function Component({ ready }) {
const ref = useRef(null)
useHotkey('Mod+S', callback, { target: ref })
if (!ready) return <Spinner /> // effect runs here, ref.current is null
return <div ref={ref} tabIndex={-1} /> // too late
}
And a target that changes after mount keeps the listener on the old element — the hotkey fires on the element the ref no longer points at, and not on the new one. Same with a plain element target, not just refs.
There's a targetChanged branch that looks like it covers the second one, but it's inside the [hotkeyString] effect, so it only runs if the hotkey string changes too. useHotkeys has a passing test for this exact case (tests/useHotkeys.test.tsx:235, "should move a registration when only the target changes") — the same test against useHotkey fails.
Failing tests, branched off 4f59e18:
https://github.com/erictheswift/tanstack-hotkeys/tree/repro/usehotkey-target-not-reresolved
git fetch https://github.com/erictheswift/tanstack-hotkeys repro/usehotkey-target-not-reresolved && git checkout FETCH_HEAD
pnpm --filter @tanstack/react-hotkeys exec vitest run tests/useHotkey-late-target.test.tsx
❯ tests/useHotkey-late-target.test.tsx (5 tests | 3 failed)
× registers once the ref is attached
× moves the registration when a ref points at a different element
× moves the registration when a plain element target changes
✓ registers when the element is present from the first render
✓ useHotkeys handles the same case
What made this hard to find: the existing test at tests/useHotkey.test.tsx:237 is called "should wait for ref to be attached", but it only checks the hotkey doesn't fire while the ref is null — it never attaches the ref and checks it starts working. The name reads like deferred registration is supported.
Two things I'm unsure about:
Is the difference from useHotkeys intentional? Both take the same target option and the docs describe it the same way.
Could it warn in dev? Both cases are silent — the hotkey just doesn't fire, or fires on the wrong element. A null ref on first run is legitimately transient so I don't know what the trigger would be, but the silence is what cost the time.
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
https://github.com/erictheswift/tanstack-hotkeys/tree/repro/usehotkey-target-not-reresolved One test file on top of 4f59e18, nothing else.
Screenshots or Videos (Optional)
No response
Do you intend to try to help solve this bug with your own PR?
Maybe, I'll investigate and start debugging
Terms & Code of Conduct
TanStack Hotkeys version
v0.10.0 (also v0.9.1)
Framework/Library version
React v19.2.5
Describe the bug and the steps to reproduce it
Two ways this bites:
A ref that's still null when the effect first runs never registers, even after it attaches:
And a target that changes after mount keeps the listener on the old element — the hotkey fires on the element the ref no longer points at, and not on the new one. Same with a plain element target, not just refs.
There's a
targetChangedbranch that looks like it covers the second one, but it's inside the[hotkeyString]effect, so it only runs if the hotkey string changes too.useHotkeyshas a passing test for this exact case (tests/useHotkeys.test.tsx:235, "should move a registration when only the target changes") — the same test againstuseHotkeyfails.Failing tests, branched off
4f59e18:https://github.com/erictheswift/tanstack-hotkeys/tree/repro/usehotkey-target-not-reresolved
What made this hard to find: the existing test at
tests/useHotkey.test.tsx:237is called "should wait for ref to be attached", but it only checks the hotkey doesn't fire while the ref is null — it never attaches the ref and checks it starts working. The name reads like deferred registration is supported.Two things I'm unsure about:
Is the difference from
useHotkeysintentional? Both take the sametargetoption and the docs describe it the same way.Could it warn in dev? Both cases are silent — the hotkey just doesn't fire, or fires on the wrong element. A null ref on first run is legitimately transient so I don't know what the trigger would be, but the silence is what cost the time.
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
https://github.com/erictheswift/tanstack-hotkeys/tree/repro/usehotkey-target-not-reresolved One test file on top of
4f59e18, nothing else.Screenshots or Videos (Optional)
No response
Do you intend to try to help solve this bug with your own PR?
Maybe, I'll investigate and start debugging
Terms & Code of Conduct