virtual icon indicating copy to clipboard operation
virtual copied to clipboard

Not support responsive size?

Open jijiseong opened this issue 1 year ago • 4 comments

Describe the bug

I use useVirtualize with useWindowSize for the responsive item size.

  const { width } = useWindowSize(); 

  const columnVirtualizer = useVirtualizer({
    horizontal: true,
    count: 100,
    getScrollElement: () => parentRef.current,
    estimateSize: () => width / 10,
    overscan: 5,
  })

Even though the width is changed, columnVirtualizer doesn`t rerendered.

There is the code about the Virtualizer instance in useVirtualizerBase (/pacakges/react-virtual/src/index.tsx, line:39)

  const [instance] = React.useState(
    () => new Virtualizer<TScrollElement, TItemElement>(resolvedOptions),
  )

Even if resolvedOptions have changed, initializing the instance only once. Is this intentional?

Your minimal, reproducible example

https://codesandbox.io/p/sandbox/rough-tdd-4wfpkr

Steps to reproduce

Refer to codesand box

Expected behavior

When I resize the window, items should rerender with new size

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

macOS

tanstack-virtual version

latest

TypeScript version

5.2.2

Additional context

No response

Terms & Code of Conduct

  • [x] I agree to follow this project's Code of Conduct
  • [x] I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.

jijiseong avatar Sep 05 '24 11:09 jijiseong

@jijiseong that is correct, estimateSize is not part of caching strategy, to re-create virtual items you can use,

getItemKey: React.useCallback((index) => index, [width]),

https://codesandbox.io/p/sandbox/sweet-sun-f35n4r?file=%2Fsrc%2FApp.tsx%3A17%2C5-17%2C62

piecyk avatar Sep 16 '24 14:09 piecyk

I'm trying to figure out how is it possible to retain the scroll position when the window or container is resized?

https://codesandbox.io/p/sandbox/quizzical-snowflake-9t5rrk?workspaceId=4639fe9e-259b-4807-83e7-6dc48e992cc6

https://github.com/user-attachments/assets/ac672971-5ab4-4e7b-a236-5f1edea449db

I have the same issue in my app where I'm trying to figure out a case where mobile is turned on it's side. Currently this throws off the scroll position as items and screen resizes.

siimsams avatar Nov 14 '24 18:11 siimsams

@jijiseong that is correct, estimateSize is not part of caching strategy, to re-create virtual items you can use,

getItemKey: React.useCallback((index) => index, [width]), https://codesandbox.io/p/sandbox/sweet-sun-f35n4r?file=%2Fsrc%2FApp.tsx%3A17%2C5-17%2C62

That's weird, but it worked. I was having issues because my estimateSize depended on too many states. I even tried using it as a direct useCallback in estimateSize and calling useEffect with virtualizer.measure() with estimateSize as a dependency, but the problem persisted (only in production did it happen).

I'd like to know why this behavior happens. It would make more sense for the library to accept an array of dependencies directly in the hook, rather than hiding it like this.

lucasdu4rte avatar Jul 24 '25 18:07 lucasdu4rte

@lucasdu4rte Yeah, it’s definitely a bit unintuitive. The hook was designed this way because in most cases, people were recreating a new estimateSize function on every render. That led to unstable measurements and degraded performance, since the virtualizer treats it as a "new" estimate and may remeasure unnecessarily.

Unfortunately, there's no golden rule, maybe having explicit prop to cacheKey that would make it more clear.

piecyk avatar Jul 31 '25 11:07 piecyk