Please tell me how to restore scrolling when using measureElement. #731
Answered
by
shunshimono
shunshimono
asked this question in
Q&A
-
Reference DiscussionIssueRestoring the scroll position during the initial rendering using the value saved in session storage Expected BehaviorThe scroll position should be restored when returning to the page Confirmed
My Code"use client";
import {
useWindowVirtualizer,
observeWindowOffset,
measureElement as defaultMeasureElement,
} from "@tanstack/react-virtual";
import { useRef } from "react";
import Link from "next/link";
import { faker } from "@faker-js/faker";
const randomNumber = (min: number, max: number) =>
faker.datatype.number({ min, max });
const sentences = new Array(100)
.fill(true)
.map(() => faker.lorem.sentence(randomNumber(20, 70)));
export default function Page() {
const listRef = useRef<HTMLDivElement | null>(null);
const cachedSizesRef = useRef<Map<number, number>>(new Map());
const measureElement = (
element: Element,
entry: ResizeObserverEntry | undefined,
instance: any,
) => {
const index = instance.indexFromElement(element);
const size = defaultMeasureElement(element, entry, instance);
cachedSizesRef.current.set(index, size);
return size;
};
const virtualizer = useWindowVirtualizer({
count: 100,
estimateSize: () => 35,
overscan: 5,
measureElement,
initialOffset: (() => {
if (typeof sessionStorage !== "undefined") {
return parseInt(
sessionStorage.getItem("virtualizer_scrollOffset") || "",
);
}
return 0;
})(),
observeElementOffset: (instance, cb) => {
return observeWindowOffset(instance, (offset) => {
if (typeof sessionStorage !== "undefined") {
sessionStorage.setItem(
"virtualizer_scrollOffset",
offset?.toString(),
);
}
cb(offset, instance.isScrolling);
});
},
});
return (
<>
<div ref={listRef} className="List">
<div
style={{
height: `${virtualizer.getTotalSize()}px`,
width: "100%",
position: "relative",
}}
>
{virtualizer.getVirtualItems().map((item) => (
<div
key={item.key}
ref={virtualizer.measureElement}
data-index={item.index}
className={item.index % 2 ? "ListItemOdd" : "ListItemEven"}
style={{
position: "absolute",
top: 0,
left: 0,
width: "100%",
transform: `translateY(${item.start}px)`,
}}
>
<h1>Row {item.index}</h1>
<Link href={"/about"}>about</Link>
<p>{sentences[item.index]}</p>
</div>
))}
</div>
</div>
</>
);
} Environment |
Beta Was this translation helpful? Give feedback.
Answered by
shunshimono
May 17, 2024
Replies: 1 comment 2 replies
-
I've found that while the scroll position is set to the correct value, the elements that were originally at that scroll position are not being displayed when restored. |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@piecyk
Thank you. I was able to resolve it by saving measurementsCache to storage when leaving the page, and setting that value to initialMeasurementsCache when remounting.
Resumable code