diff --git a/packages/@react-aria/virtualizer/src/ScrollView.tsx b/packages/@react-aria/virtualizer/src/ScrollView.tsx index 0b94ba31c09..995b3b95d33 100644 --- a/packages/@react-aria/virtualizer/src/ScrollView.tsx +++ b/packages/@react-aria/virtualizer/src/ScrollView.tsx @@ -184,7 +184,7 @@ export function useScrollView(props: ScrollViewProps, ref: RefObject { @@ -198,7 +198,7 @@ export function useScrollView(props: ScrollViewProps, ref: RefObject(null); - let [update, setUpdate] = useState({}); + let [update, setUpdate] = useState<{} | false>(false); useLayoutEffect(() => { if (!isUpdatingSize.current && (lastContentSize.current == null || !contentSize.equals(lastContentSize.current))) { // React doesn't allow flushSync inside effects, so queue a microtask. @@ -224,7 +224,9 @@ export function useScrollView(props: ScrollViewProps, ref: RefObject { - updateSize(fn => fn()); + if (update) { + updateSize(fn => fn()); + } }, [update]); let onResize = useCallback(() => { diff --git a/packages/@react-spectrum/list/chromatic/ListView.stories.tsx b/packages/@react-spectrum/list/chromatic/ListView.stories.tsx index 5301c55fb9a..ba36201abb5 100644 --- a/packages/@react-spectrum/list/chromatic/ListView.stories.tsx +++ b/packages/@react-spectrum/list/chromatic/ListView.stories.tsx @@ -168,3 +168,37 @@ export const Empty = { render: TemplateEmptyState, name: 'empty state' }; + +export const SuspendedItem = { + render: (args) => { + return ( + +
+ + + + Item 1 + + + Item 2 + +
+
+ ); + }, + name: 'suspended item' +}; +let data: string; +const promise = new Promise((resolve) => setTimeout(resolve, 500)).then(() => { + data = 'data'; +}); +const useData = () => { + if (!data) { + throw promise; + } + return data; +}; +function WithSuspense({children}: { children: React.ReactNode }) { + useData(); + return <>{children}; +}