react-virtualized
react-virtualized copied to clipboard
scrollToRow, scrollToPosition no longer works with WindowScroller after updating React to v16.8
For my case, I've tested that it works for both methods without a WindowScroller
. Any idea what's happening
Please reference this issue: https://github.com/bvaughn/react-virtualized/issues/1179#issuecomment-593502991
What is the current behavior?
Calling scrollToRow
and scrollToPosition
no longer scrolls properly, but the functions are defined and I can log to the console. It just failed silently.
What is the expected behavior?
It should simply scroll to the right position / row.
Which versions of React and react-virtualized, and which browser / OS are affected by this issue? Did this work in previous versions of react-virtualized?
Browser | Chrome v80 |
OS | OSX 10.15.3 |
React | 16.8.5 |
React DOM | 16.8.5 |
react-virtualized | 9.21.2 |
There are multiple open issues related to this same problem, some referencing List/Grid and others referencing WindowScroller. None of the workarounds referenced in all of these issues are working and downgrading react is not a viable solution for us.
Any idea if this is going to be fixed soon?
As a quick workaround, this have worked for me - restrict the version to: "react-virtualized": "9.21.1" in package.json. As I noticed the patch version updated had introduced the issue.
I have the same problem with this.Are you deal with this problem?
Sorry lads, forgot to post. My quick workaround is like this:
import getScrollYFromElementOrWindow from 'simply-utils/dist/dom/getScrollYFromElementOrWindow';
import tryUntil from 'simply-utils/dist/utils/tryUntil';
...
/*
* Put this as the `ref` prop of the `List` component
*/
const handleRef = useCallback((ref) => {
if (ref !== null) {
/**
* * TEMP Fix for virtualized list scrollToPosition not working issue when using with WindowScroller
*
* @TODO: Wait for PR
* Ref: https://github.com/bvaughn/react-virtualized/issues/1179
*/
if (windowScrollerEnabled) {
// Override and fix scrollToPosition
ref.scrollToPosition = (scrollTop: number) => tryUntil(() => {
// Use the scroll element ref passed from props
const scrollEl = scrollElementRef?.current
if (scrollEl) {
// Use the `scrollTo` method from the passed element
scrollEl.scrollTo({ top: scrollTop })
// Get updated scroll top form the element
const updatedScrollTop = getScrollYFromElementOrWindow(scrollEl)
// Done if targeted scroll top is met (case: true), or
// Try next if targeted scroll top is not met (case: false)
return updatedScrollTop === scrollTop
}
// Try next
return false
}, 30, 0)
// Override and fix scrollToRow
ref.scrollToRow = (index: number) => {
const scrollTop = ref.getOffsetForRow({ index })
ref.scrollToPosition(scrollTop)
}
}
}
}, [scrollElementRef, windowScrollerEnabled])
Btw, simply-utils
is just the open-source npm utils library I created. The tryUntil
util is just keep calling the callback until success.
Sorry lads, forgot to post. My quick workaround is like this:
import getScrollYFromElementOrWindow from 'simply-utils/dist/dom/getScrollYFromElementOrWindow'; import tryUntil from 'simply-utils/dist/utils/tryUntil'; ... /* * Put this as the `ref` prop of the `List` component */ const handleRef = useCallback((ref) => { if (ref !== null) { /** * * TEMP Fix for virtualized list scrollToPosition not working issue when using with WindowScroller * * @TODO: Wait for PR * Ref: https://github.com/bvaughn/react-virtualized/issues/1179 */ if (windowScrollerEnabled) { // Override and fix scrollToPosition ref.scrollToPosition = (scrollTop: number) => tryUntil(() => { // Use the scroll element ref passed from props const scrollEl = scrollElementRef?.current if (scrollEl) { // Use the `scrollTo` method from the passed element scrollEl.scrollTo({ top: scrollTop }) // Get updated scroll top form the element const updatedScrollTop = getScrollYFromElementOrWindow(scrollEl) // Done if targeted scroll top is met (case: true), or // Try next if targeted scroll top is not met (case: false) return updatedScrollTop === scrollTop } // Try next return false }, 30, 0) // Override and fix scrollToRow ref.scrollToRow = (index: number) => { const scrollTop = ref.getOffsetForRow({ index }) ref.scrollToPosition(scrollTop) } } } }, [scrollElementRef, windowScrollerEnabled])
Btw,
simply-utils
is just the open-source npm utils library I created. ThetryUntil
util is just keep calling the callback until success.
Hey Michael! Could you give more details how to use your solution? Maybe some https://codesandbox.io example?
@pro2html May I know which part you don't understand? It is hard and time consuming for me to recreate a full code example now since it's a bit legacy. And I do recommend you switching to the new package https://github.com/bvaughn/react-window.
Thanks for the link, Michael!
I think it will be easier to use the newer version than try to fix the old one.
Thank you for responding to my message, I appreciate it!
4 сент. 2021 г., в 08:57, Michael Chan L. S. @.***> написал(а):
@pro2html https://github.com/pro2html May I know which part you don't understand? It is hard and time consuming for me to recreate a full code example now since it's a bit legacy. And I do recommend you switching to the new package https://github.com/bvaughn/react-window https://github.com/bvaughn/react-window.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/bvaughn/react-virtualized/issues/1507#issuecomment-912915030, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACQ2VSGUFZBCTSXPVETBBRLUAGYLNANCNFSM4LACKL4A. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
@pro2html hello, I cannot quite get how to * Put this as the ref
prop of the List
component * and how to use ref. scrollToRow later.
@pro2html and can you share the implementation of tryUtil function you're using?
I use the suggestion of @michchan , here is how I made it work:
let tableRef = useRef<Table | null>(); // create a ref, so we can calling it in future
const handleRef = useCallback((ref: Table | null) => {
if (ref !== null) {
ref.scrollToPosition = (scrollTop: number) =>
tryUntil(
() => {
const scrollEl = window;
if (scrollEl) {
scrollEl.scrollTo({ top: scrollTop, behavior: 'smooth' });
const updatedScrollTop = getScrollYFromElementOrWindow(scrollEl);
console.log(updatedScrollTop);
return updatedScrollTop === scrollTop;
}
// Try next
return false;
},
30,
0,
);
ref.scrollToRow = (index: number) => {
const scrollTop = ref.getOffsetForRow({ index, alignment: 'center' });
ref.scrollToPosition(scrollTop);
};
}
}, []);
and in the <Table component I put this in the ref prop:
<Table ref={(ref) => { handleRef(ref); tableRef.current = ref; }}
And now we can use the function:
tableRef.current?.scrollToRow(row);