A way to create additional render regions #663
Replies: 2 comments
-
Many thanks to @NickGerleman for putting together a proposal for the same problem years ago: https://github.com/react-native-community/discussions-and-proposals/pull/335/files#diff-e23f6c45e9b607cd5ed0f124fd016bc16cd1dffc67ee354cd9f93799da962024 Even though the proposed APIs have never exposed to the user, he laid the ground work in these PRs: We should be able to implement such feature with very minimal effort thanks to his prior work. |
Beta Was this translation helpful? Give feedback.
-
Implemented in #672. |
Beta Was this translation helpful? Give feedback.
-
There's a common use-case in the FlatLists where one might want to start the initial scroll position from the middle of the list, let's say. This is required when you need to remember the last location user left and start the focus from that location. You do that to make sure the element which needs to gain focus is rendered and in the viewport, so it is focusable.
There's a drawback of this approach, though. Using
initialScrollIndex
disables scroll-to-top optimization on the list which makes sure 1 viewport length worth of elements always stay rendered in the list forscroll-to-top
actions. This optimization is important, users can experience blank spaces in the list on scroll to top actions otherwise due to the nature of virtualization. The other aspect of the problem is, if there's no element rendered when we scroll to a position (top, in this case), we simply can't move focus to anywhere reliably. Focus recovery attempts also fail due to this aspect.Here's the example I came up with:
Screen.Recording.2024-02-14.at.20.31.12.mov
The list starts around the middle, at the 6th element. It has
initialScrollIndex={6}
to achieve that. So, scroll-to-top optimization is disabled which means that we should experience blank areas if we scroll to top. Every element on the list triggers ascrollToOffset({ offset: 0, animated: false })
action to test this.I press enter to trigger the action and focus sort of gets lost and moves to
Components
tab above. What we'd expect instead is it should be recovered to the element0
.If you pay a bit of attention, you can spot the blank space for a split second. You can easily see that if you forward/rewind to around 9th second. I'll save you from the trouble, this is how it looks:
So, we always need prerendered elements when we suddenly scroll position to a position. I propose to provide a prop called
additionalRenderRegions
to feed predefined regions to keep them out of virtualization. This way, people can use it to meet all their needs. Some might want to scroll-to-top, some to bottom, some might have a requirement to jump multiple parts of the screen. Providing such ability should cover them all.It should look something like this:
Beta Was this translation helpful? Give feedback.
All reactions