Replies: 2 comments 1 reply
-
You can use something like this const items = rowVirtualizer.getVirtualItems();
const isMountedScrollToBottomRef = useRef(false);
const scrollToBottom = useCallback(
({ behavior = "smooth" }: { behavior?: ScrollToOptions["behavior"] } = {}) => {
requestAnimationFrame(() => {
rowVirtualizer.scrollToIndex(footerIndex, {
align: "end",
behavior,
});
})
},
[rowVirtualizer, footerIndex],
);
useLayoutEffect(() => {
if (!isMountedScrollToBottomRef.current && items.length > 0) {
isMountedScrollToBottomRef.current = true;
scrollToBottom({ behavior: "auto" });
}
}, [items, scrollToBottom]); |
Beta Was this translation helpful? Give feedback.
-
This is a bug, which provided by lib from creation. A lot of issues was closed with MRs, which wasnt fix anything. const parentRef = useRef<HTMLDivElement>(null);
const { rows } = table.getRowModel();
const virtualizer = useVirtualizer({
count: rows.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 60,
overscan: 1,
});
const handleScrollToTop = () => {
virtualizer.scrollToIndex(0, {
behavior: 'smooth',
align: 'start'
})
};
const sleep = (ms: number) => {
return new Promise((resolve) => setTimeout(resolve, ms))
}
const handleScrollToBottom = async () => {
if (!parentRef.current) return
let currentScrollBottom = parentRef.current.offsetHeight;
const totalScrollBeltHeight = virtualizer.getTotalSize();
while (currentScrollBottom < totalScrollBeltHeight) {
virtualizer.scrollToIndex(rows.length - 1, {
behavior: 'smooth',
align: 'end'
})
await sleep(50);
currentScrollBottom = parentRef.current.scrollTop + parentRef.current.offsetHeight;
console.log(currentScrollBottom, totalScrollBeltHeight)
}
console.log('end', currentScrollBottom, totalScrollBeltHeight)
}; Looks terrible, works terrible and as lib on my opinion is terrible. But it is only one workaround which really works for me. const handleScrollToTop = () => {
if (!parentRef.current) return
parentRef.current.scrollTo({
top: 0,
behavior: 'smooth'
})
};
const sleep = (ms: number) => {
return new Promise((resolve) => setTimeout(resolve, ms))
}
const handleScrollToBottom = async () => {
if (!parentRef.current) return
let currentScrollBottom = parentRef.current.offsetHeight;
const totalScrollBeltHeight = virtualizer.getTotalSize();
let emptyIterationCount = 0;
while (currentScrollBottom < totalScrollBeltHeight && emptyIterationCount < 2) {
parentRef.current.scrollTo({
top: currentScrollBottom,
behavior: 'smooth'
})
await sleep(50);
const newScrollBottom = parentRef.current.scrollTop + parentRef.current.offsetHeight
if (newScrollBottom === currentScrollBottom) {
emptyIterationCount++;
continue
}
currentScrollBottom = newScrollBottom;
}
}; |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm using useVirtualizer, dynamic mode
Like a chat message list, i want to start at the bottom of the scroller
I currently do this, but the result is not at the bottom, i guess i shoud do this when the measument is end, but there isn't a event
useEffect(() => { rowVirtualizer.scrollToIndex(data.length - 1) }, [])
Beta Was this translation helpful? Give feedback.
All reactions