I’m trying to implement the Scroll snap effect in react. Scroll snap is when you scroll a little and it auto scrolls to the next card in the list.
In this example, react-virtuoso displays only the first few cards (due to overscan={{ main: 1000, reverse: 1000 }}
):
<code>'use client';
import React, { forwardRef, HTMLProps } from 'react';
import { Virtuoso } from 'react-virtuoso';
import { FeedCard, useGetProductsQuery } from '@/entities/product';
import { SHomeScreen } from './home-screen.styles';
const components = {
List: forwardRef<HTMLDivElement, HTMLProps<HTMLDivElement>>(
({ style, children, ...props }, ref) => {
return (
<div
style={{
overflow: 'scroll',
scrollSnapType: 'y mandatory',
height: '100vh',
...style,
}}
ref={ref}
{...props}
>
{children}
</div>
);
}
),
Item: forwardRef<HTMLDivElement, HTMLProps<HTMLDivElement>>(
({ style, children, ...props }, ref) => {
return (
<div
style={{
scrollSnapAlign: 'start',
...style,
}}
ref={ref}
{...props}
>
{children}
</div>
);
}
),
};
export function HomeScreen() {
const { data, fetchNextPage } = useGetProductsQuery();
return (
<SHomeScreen>
<Virtuoso
useWindowScroll
data={data || []}
itemContent={(_, itemData) => <FeedCard {...itemData} />}
components={components}
overscan={{ main: 1000, reverse: 1000 }}
endReached={() => {
fetchNextPage();
}}
/>
</SHomeScreen>
);
}
</code>
<code>'use client';
import React, { forwardRef, HTMLProps } from 'react';
import { Virtuoso } from 'react-virtuoso';
import { FeedCard, useGetProductsQuery } from '@/entities/product';
import { SHomeScreen } from './home-screen.styles';
const components = {
List: forwardRef<HTMLDivElement, HTMLProps<HTMLDivElement>>(
({ style, children, ...props }, ref) => {
return (
<div
style={{
overflow: 'scroll',
scrollSnapType: 'y mandatory',
height: '100vh',
...style,
}}
ref={ref}
{...props}
>
{children}
</div>
);
}
),
Item: forwardRef<HTMLDivElement, HTMLProps<HTMLDivElement>>(
({ style, children, ...props }, ref) => {
return (
<div
style={{
scrollSnapAlign: 'start',
...style,
}}
ref={ref}
{...props}
>
{children}
</div>
);
}
),
};
export function HomeScreen() {
const { data, fetchNextPage } = useGetProductsQuery();
return (
<SHomeScreen>
<Virtuoso
useWindowScroll
data={data || []}
itemContent={(_, itemData) => <FeedCard {...itemData} />}
components={components}
overscan={{ main: 1000, reverse: 1000 }}
endReached={() => {
fetchNextPage();
}}
/>
</SHomeScreen>
);
}
</code>
'use client';
import React, { forwardRef, HTMLProps } from 'react';
import { Virtuoso } from 'react-virtuoso';
import { FeedCard, useGetProductsQuery } from '@/entities/product';
import { SHomeScreen } from './home-screen.styles';
const components = {
List: forwardRef<HTMLDivElement, HTMLProps<HTMLDivElement>>(
({ style, children, ...props }, ref) => {
return (
<div
style={{
overflow: 'scroll',
scrollSnapType: 'y mandatory',
height: '100vh',
...style,
}}
ref={ref}
{...props}
>
{children}
</div>
);
}
),
Item: forwardRef<HTMLDivElement, HTMLProps<HTMLDivElement>>(
({ style, children, ...props }, ref) => {
return (
<div
style={{
scrollSnapAlign: 'start',
...style,
}}
ref={ref}
{...props}
>
{children}
</div>
);
}
),
};
export function HomeScreen() {
const { data, fetchNextPage } = useGetProductsQuery();
return (
<SHomeScreen>
<Virtuoso
useWindowScroll
data={data || []}
itemContent={(_, itemData) => <FeedCard {...itemData} />}
components={components}
overscan={{ main: 1000, reverse: 1000 }}
endReached={() => {
fetchNextPage();
}}
/>
</SHomeScreen>
);
}
as soon as I remove overflow: scroll
in the List component, everything starts working (Except Scroll snap)