question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Focus is lost during list re-order

See original GitHub issue
  • Check if updating to the latest Preact version resolves the issue (latest is still impacted)

Describe the bug Focus is lost during list re-order. When a list re-renders, if the focused item is moved to later in the source order, it loses focus.

To Reproduce As shown in this Code Sandbox If a list is re-ordered: focus is properly preserved when moving up in the source order, but not down in the source order. (All items have keys that are stable and not indexed based) preact-reorder-focus-bug

Steps to reproduce the behavior:

  1. Go to the Code Sandbox
  2. Click on an item in the list
  3. Move the item up with the up arrow key, and observe the focus remains on the correct item.
  4. Move the item down with the down arrow key, and observe the focus is lost.

Expected behavior The item should maintain focus no matter which direction in the source order it moves.

Similar issue This is similar to: Input loses focus when conditionally rerendering other divs #540. However, since this issue is not about conditional rendering, only list rendering, and because that issue is closed whereas this issue effects the latest tested version (10.5.14), I believe this warrants it’s own ticket.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
developitcommented, Sep 10, 2021

Interesting - this is an unfortunate effect of an optimization Preact does: we “detect” small swap or shift movements within a list of keyed items and only invoke a single insertBefore() to move one of the items because we know the other affected item will end up in the correct place as a result. In order for this to work, we always move the first out-of-place item.

In your demo, hitting the up arrow key shifts the item up, which means it’s the first out-of-place item in the newly sorted list of items. Conversely, the down arrow key shifts the item down, which means the item it was shifted “around” (the next item in the list) will be the first out-of-place item in the new set of children.

The result is that pressing “up” moves the previous item to after the selected item, whereas pressing “down” moves the selected item to after the next item, which means you lose focus.

We removed manual focus management code from Preact, because it’s really difficult to justify the performance impact. I do think this is an interesting case to explore fixes for (rather than documenting as a difference to React), but we’d be looking for ways of taking focus state into account during diffing rather than any sort of manual focus restoration.

1reaction
mattorchardcommented, Aug 13, 2021

Ahh, I see. I hadn’t clued in that it was just a matter of swapping the other element for the focused one to remain selected.

Given that this does work in React (as you mentioned above, and shown in this React CodeSandbox): Should this issue still be considered a bug for Preact? Either to fix, or to add to the “Differences to React” docs?

Read more comments on GitHub >

github_iconTop Results From Across the Web

React.js - input losing focus when rerendering - Stack Overflow
When a re-rendering occurs, if the same key is seen, this will tell React don't clobber and regenerate the view, instead reuse. Then...
Read more >
accessibility - Where to put focus after deleting an item in a list
Move the focus to the item before the deleted item. Instead of leaving the focus on the position in the list, move the...
Read more >
Is there a pattern to avoid losing focus on an input element ...
Each time there's a change in the input, the entire list is re-rendered and the input field loses focus. However, I tried to...
Read more >
RecyclerView items lose focus with notify*Changed ...
When an item in a RecyclerView is holding focus (and/or a11y focus) and the RecyclerView's adapter receives a notify*Changed() (e.g., notifyDatasetChanged() ...
Read more >
Organize email in mailboxes on iPhone - Apple Support
Organize your mail with mailboxes · View mailboxes: Select the checkboxes next to the mailboxes you want to include in the mailboxes list....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found