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

[BUG] Attaching resulting ref to a different element stops the shortcuts/hotkeys from working #1116

Open
vilemj-Viclick opened this issue Jan 9, 2024 · 6 comments · May be fixed by #1132
Open

Comments

@vilemj-Viclick
Copy link

vilemj-Viclick commented Jan 9, 2024

Describe the bug

If you attach the result of the hook useHotkeys to a different element than it was initially attached to, it breaks.

To Reproduce

Steps to reproduce the behavior:

  1. Have code of the sorts const ref = useHotkeys(...); in your component.
  2. Use the ref like this initially: <element1 ref={ref} />
  3. Then based on a condition of some sort use the ref like this: <element2 ref={ref} />
  4. The shortcuts stop working

I made a CodePen to illustrate this better.

Here's the gist of the demo:

It renders either or <textarea /> based on a button toggle. Supposedly a situation where you toggle between a multi-line and simple input situation. But it's purely an example.

When focus is inside any of the input tags (input or textarea) pressing Enter increments a counter. The value of the counter is rendered as well.

After you use the Toggle button (be it once or multiple times) the Enter key no longer increments the counter.

Expected behavior

When the ref is attached to a different instance the eventHandler should re-attach. => Call addEventHandler on the new instance. Of-course after clearing the old one. The old instance can stay in the DOM after all, though it does not in my example.

Environment:

  • Desktop
  • OS: All (I am on Mac OS Sonoma)
  • Browser: All (I use Vivaldi)
  • Browser version: All (6.5.3206.50 (Stable channel) (arm64))
  • Package version: 4.4.3

Additional context

How to fix:

To fix this, the returned Ref will need to be a RefCallback<T> instead of MutableRefObject<T>.
By passing a RefCallback, your callback will be called by React every time the instance it's attached to changes.

I can and may submit a Pull-Request with a fix.

@JohannesKlauss
Copy link
Owner

Changing the return type does not change the behavior of the code. Typescript ist not present during runtime.

@chekrd
Copy link

chekrd commented Jan 9, 2024

@JohannesKlauss I am sure he uses TS to describe the desired JS implementation as TS is a great tool for this.

@vilemj-Viclick
Copy link
Author

Changing the return type does not change the behavior of the code. Typescript ist not present during runtime.

It sure does not.
But by using a callback, your code can actually react (haha... 😄) to a change in the element to which the ref is attached to.

I already have working code including a test failing without my changes.
I hope it will all make sense when presented with my suggestions.

@vilemj-Viclick
Copy link
Author

Here's the PullRequest: #1117

@JohannesKlauss
Copy link
Owner

Thank you for work, I'll have a look into it!

@zeorin
Copy link

zeorin commented Feb 8, 2024

I have a simpler implementation here: #1132

@zeorin zeorin linked a pull request Feb 8, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants