-
-
Notifications
You must be signed in to change notification settings - Fork 52
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: shift
causes render artifacts when items are added/removed mid-list
#284
Comments
It is not well documented, but by design, shift prop should be true when items are increased/decreased from top. And it should be false when you do other actions which increase/decrease items. Both true and false is OK when you do not increase/decrease items. That is based on an assumption that increase/decrease at top and increase/decrease at mid/bottom will not happen at the same one render. In that shuffling/refreshing like case it might be better to set false to shift. |
Got it... I wonder if I could give some more feedback that might adjust your thinking on how My concern is that The examples in Storybook that use The solution to this (and I think a much more common use case) is to check whether to https://cloudup.com/c_Nm48VG4y2 Possible solutionIs it possible for Virtua to prevent the wrong thing from happening, by deciding itself whether or not to shift? Whenever it makes scroll adjustments, it checks whether the first items have changed (by comparing What are your thoughts @inokawa? |
Thank you for your feedback! I agree with that staying true or false would be better, as long as its code can be small. Contribution is welcome but I'm not sure it's possible. I didn't find out a way to do it completely when I implemented |
hi @mattwondra , curious if you found any workaround for this issue? |
@LookRain Hiya! We rolled our own checking to see whether
This ensures that every time /**
* Virtua's `shift` prop helps maintain scroll position when prepending items (like message history).
* Unfortunately it's finicky and must only be `true` when the beginning of the list changes, otherwise
* rendering gets broken (see: https://github.com/inokawa/virtua/issues/284).
*
* Virtua also requires `shift` to be correct on the same render pass when items are updated — so we can't
* just use `useEffect` and `useState` to monitor items and update `shift` since those will update _after_ the
* render pass. Instead, we use refs to check if the underlying data has changed on each render pass, and
* update a `shift` ref in the same pass.
*
* That's all encapsulated in this handy hook, to keep the logic out of the component.
*/
const useShift = (listData?: MessageListData) => {
const previousListData = useRef<MessageListData | undefined>()
const shouldShift = useRef<boolean>()
if (listData !== previousListData.current) {
if (listData?.messages[0]?.id !== previousListData.current?.messages[0]?.id) {
shouldShift.current = true
} else {
shouldShift.current = false
}
previousListData.current = listData
}
return shouldShift.current
} |
Describe the bug
shift
works great when prepending items, but causes lots of rendering artifacts when adding/removing items from anywhere else in the list. To see it, enableshift
with a list of items of varying heights and then:To Reproduce
Use the story in my branch and check out this demo for examples:
Screen.Recording.2023-12-12.at.4.50.54.PM.mp4
Expected behavior
Rendering glitches should not happen with
shift
enabled, no matter where in the list items are being added / removed.Platform:
Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered: