-
-
Notifications
You must be signed in to change notification settings - Fork 305
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] Simple header breaks restore state location #1081
Comments
I tried to debug this issue myself for a few hours, but honestly I just don't understand the urx streams at all, I can't even manage to figure out how to follow the flow. In the stateLoadSystem, I found this which I think is the getState callback
And it seems that when I log the scrollTop is saving the correct position. I tried modifying the state.tsx example by adding a 200px height header. If I am at the very top and I save, the scrollTop is 0, when I restore it seems to compensate for the header a second time and it scrolls down 200px in addition to the scrollTop value. So if I scroll to item 0, and save, scrollTop is already 200px, and when I restore, it goes to item 8, which is 400px. It works perfectly if I manually subtract the header height from scrollTop before I save. Though I tried to retrieve the value from the stream it seems to be in, I see it grabbed from useEmitterValue in Virtuoso.tsx but whatever I tried I couldn't get it. I'd really love to help and debug it myself, but I can't even figure out where it's restoring it from, I think it's getting piped to initialTopMostItemIndex, but I can't make heads or tails of it. |
This is most likely a legit issue, but I am stretched very thin with my time; it's unlikely for me to be able to get to it at any point soon. |
I think I figured out a solution. The core of the issue is the scrolling restoration uses: It's off-setting the saved scrollTop from the first indexed item, but that doesn't account for the Header height. I attempted to grab the header height from domIOsystem in the tup in stateLoadSystem.ts:
After lots of debugging and adding a new isHeaderHeightSet bool in the Header: component inside Virtuoso.tsx because there was no way to tell if it was 0 or if it wasn't set yet, I realized that even after a stream var is set, for the first few cycles of the app they are stuck with their default values. I think maybe all the defined streams should be set on a reload before attempting to process anything else. I didn't need that boolean anyway since I realized I needed to check if a Header component was even set, but listComponentPropsSystem isn't exported so I couldn't find a way to check that or the props outside of the main Virtuoso.tsx. While debugging I found I can add
and that fails because scrolledToInitialItem && scrollScheduled are already true. This is a solution in stateLoadSystem that works:
But it bypasses the initialTopMostItemIndexSystem, and also always expects the height so it's not a good solution. So if the headerHeight wasn't available before all the checks, then maybe after would be the ideal time to get it. So this is the final solution:
I played with the skipFrames, and it needs to be at least 3 before the headerHeight value is properly populated, it was 4 to begin with, so all good now. |
Describe the bug
If restoreStateFrom is used along with components Header, then the restoreStateFrom does not restore to the correct location
Reproduction
https://codesandbox.io/p/sandbox/sandpack-project-forked-x869rf?file=%2FApp.js%3A193%2C15
To Reproduce
Steps to reproduce the behavior:
Scroll up, click the "save" button. Click the "restore" button. See the location jump.
Expected behavior
Comment out line 194.
Scroll up, click the "save" button. Click the "restore" button. See the location not jump.
The text was updated successfully, but these errors were encountered: