Troubleshooting React Virtuoso
React Virtuoso tries to hide as much complexity as possible while maintaining sensible behavior with any configuration. The magic has certain limits, so please check this section if something does not work as you expect.
List is jumping around or misbehaving
Section titled “List is jumping around or misbehaving”The list relies on measuring the item sizes and dynamically updating its position based on the received data. This is more of an art than science in some use cases, especially when it comes to reverse scrolling. Certain content factors like dynamic content (images, iframes, etc.) can cause trouble.
To get a better sense of whether this is your case, you can enable debug logging either by setting the logLevel property to LogLevel.DEBUG or by setting a globalThis.VIRTUOSO_LOG_LEVEL to LogLevel.DEBUG.
Import LogLevel from the react-virtuoso package.
Afterward, set the logging level in your browser to "all levels" and observe the messages for unexpected item sizes reported outside of the normal render cycle.
List does not scroll to the bottom / items jump around
Section titled “List does not scroll to the bottom / items jump around”This is the most common setup error. It happens because the DOM elements inside the items (or the items themselves) have margins.
Why margins break Virtuoso
Section titled “Why margins break Virtuoso”Virtuoso measures item sizes using ResizeObserver, which reports the contentRect of each element. The contentRect does not include margins. When items have margins, Virtuoso calculates a smaller total height than the actual rendered content, preventing users from scrolling to the end of the list.
How to diagnose
Section titled “How to diagnose”- Open your browser’s developer tools
- Select a list item element
- Go to the Computed tab (next to Styles)
- Look for non-zero
margin-topormargin-bottomvalues
Common culprits
Section titled “Common culprits”These HTML elements have default margins that often cause issues:
<p>- paragraphs have top and bottom margins<h1>through<h6>- headings have significant margins<ul>,<ol>- lists have top and bottom margins<blockquote>- block quotes have margins<pre>- preformatted text has margins
Replace margins with padding. For elements with default margins, explicitly set margin: 0 and use padding instead:
jsxI get “Error: zero-sized element, this should not happen”
Section titled “I get “Error: zero-sized element, this should not happen””Technically, this could have been a warning, but it is usually a sign of something not working as expected, so throwing an error is better for you. This means that you either have empty items (something which Virtuoso can’t support), or you are hitting a bug of some sort (could be due to some exotic integration scenario).
If you have zero-height items, you need to filter those out before passing them to the component. The internal data structure needs a distinct position for each item. There’s no way to fix this.
Components remount on every scroll
Section titled “Components remount on every scroll”If your list items remount (lose state, re-run effects) every time you scroll, you’re likely defining components inline.
Why this happens
Section titled “Why this happens”When you define a component function inside your render function, React creates a new component type on every render. Even if the JSX looks identical, React treats it as a different component and unmounts/remounts it.
jsxDefine components outside the render function, or use React.memo for complex item content:
jsxjsxSee the custom rendering documentation for more details on component customization patterns.
Webpack dev server shows an error Uncaught Error: ResizeObserver loop completed with undelivered notifications
Section titled “Webpack dev server shows an error Uncaught Error: ResizeObserver loop completed with undelivered notifications”This is a known issue with the Webpack dev server and the ResizeObserver API used by Virtuoso. To silence this error, apply the following configuration to your server:
javascriptSentry catches an error ResizeObserver loop limit exceeded or ResizeObserver loop completed with undelivered notifications
Section titled “Sentry catches an error ResizeObserver loop limit exceeded or ResizeObserver loop completed with undelivered notifications”Check this thread.
Experiencing something else?
Section titled “Experiencing something else?”Please open an issue with reproduction in codesandbox or stackblitz.