TanStack / virtual

🤖 Headless UI for Virtualizing Large Element Lists in JS/TS, React, Solid, Vue and Svelte
https://tanstack.com/virtual
MIT License
5.55k stars 303 forks source link

HMR (live reload, fast refresh) broke render in React #750

Open dartess opened 4 months ago

dartess commented 4 months ago

Describe the bug

After the hot reload, new list items are not rendered

Your minimal, reproducible example

https://stackblitz.com/edit/tanstack-virtual-dc5j1h?file=src%2Fmain.tsx,src%2FRowVirtualizerFixed.tsx&preset=node

Steps to reproduce

  1. open repl
  2. edit console.log('foo'); with some different text
  3. press cmd/ctrl+S for save and live reload
  4. scroll list
  5. see that list is empty

Expected behavior

it should just work

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

any platform , any bundler — vite, wepack, rspack

tanstack-virtual version

3.8.1

TypeScript version

No response

Additional context

No response

Terms & Code of Conduct

mr-devboy commented 4 months ago

Same here

hophiphip commented 2 months ago

TLDR: scrollElement gets cleared in _didMount and that is why virtualizer stops working.

The only methods that can change scrollElement are: _willUpdate and _didMount.

  1. On the initial run _willUpdate and _didMount are called in this order: 2024-08-29-16:45:41-screenshot

  2. After triggering HMR _willUpdate and _didMount will be called in this order: 2024-08-29-16:48:18-screenshot

[2] - This means scrollElement gets cleared and set to null which "breaks" the virtualizer.

You can debug this in this CodeSandbox: https://codesandbox.io/p/devbox/4wnzrm There you can find fixed useVirtualizerBase in src/hooks/useVirtualizerFixed.tsx.

Video how to reproduce the bug: https://github.com/user-attachments/assets/90b33824-e89f-42f1-a98a-98936d5f1227

See fix in: https://github.com/TanStack/virtual/pull/820