TanStack / virtual

🤖 Headless UI for Virtualizing Large Element Lists in JS/TS, React, Solid, Vue and Svelte

Home Page:https://tanstack.com/virtual

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Scroll to not working + warning about flushSync

hornta opened this issue · comments

Describe the bug

The scrollToIndex doesn't seem to work and I'm getting a warning about flushSync. I'm guessing the scrollTo doesn't work because of whatever triggers the warning.

How would I go about this issue? I'm using react-virtual@3.2.1 and latest react 18 version.

Warning: flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task.

9c87ccf6-833d-46d6-88cd-14325ce29fda

Your minimal, reproducible example

https://github.com/hornta/react-virtual-flushsync-scrollto
https://stackblitz.com/~/github.com/hornta/react-virtual-flushsync-scrollto

Steps to reproduce

Clone repository, run pnpm dev and open http://localhost:5173 and click the input field, scroll down to option in the bottom and click that. Now click the input again and observe the error in console and how you are not scrolled down to the item.

Expected behavior

No warning in console and scrollTo should work.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

Windows, Chrome

tanstack-virtual version

3.2.1

TypeScript version

5.4.5

Additional context

No response

Terms & Code of Conduct

  • I agree to follow this project's Code of Conduct
  • 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.

Update:
I solved the problem with the scroll to. I wrapped the scrollToIndex with a requestIdleCallback and now it successfully scrolls to the index. (I've not updated the reproducible example with this fix.)

	useLayoutEffect(() => {
		if (selectedIndex && isOpen) {
			requestIdleCallback(() => {
				rowVirtualizer.scrollToIndex(selectedIndex, { align: "center" });
			});
		}
	}, [selectedIndex, isOpen, rowVirtualizer]);

However the warning is still there but I can ignore it for now until a fix is found. I'd be very willing to help out debugging if a maintainer or contributor wants to look into this.

Like commented on discord, here we have two issues

  • first is the size middleware, here you can't direclty mutate the floating as the virutlizer use the height when resolving scroll logic, there is example in floating docs where @atomiks is using flush sync

https://codesandbox.io/s/l10rjs?file=/src/App.tsx

  • second in useLayoutEffect scroll element can be null, we can use the floating elements to wait till next render like
useLayoutEffect(() => {
  if (!elements.floating) return

  if (selectedIndex && isOpen) {
    rowVirtualizer.scrollToIndex(selectedIndex, { align: "center" });
  }
}, [selectedIndex, isOpen, rowVirtualizer, elements.floating]);