Эффект моргания и отката при прокрутке виртуализации скролла
Сделал виртуализацию скролла, но при использовании совместно с
flex-wrap: wrap;
justify-content: center;
Подскажите плиз кто знает как можно решить проблему. Вот код
import {memo, MutableRefObject, ReactNode, useEffect, useRef, useState} from 'react';
import {classNames} from "shared/lib/classNames/classNames";
import {useQuery} from "@apollo/client";
import {GET_VEHICLES} from "shared/api/GET_VEHICLES";
import {useDataContext} from "features/DataContext";
import cls from "./CardShip.module.scss"
import {Vehicle} from "entity/Vehicle";
interface CardShipProps {
className?: string
children?: ReactNode
}
export const CardShip = memo((props: CardShipProps) => {
const {loading, error, data} = useQuery(GET_VEHICLES);
const {dataSort, setDataSort} = useDataContext()
const [startSlice, setStartSlice] = useState(0)
const rootRef = useRef() as MutableRefObject<HTMLDivElement>
const rowShips = 330
const visibleShips = Math.floor(window.innerHeight / rowShips) * 8
const getBottomHeight = () => {
// console.log(rowShips,dataSort.length,startSlice)
return (rowShips + 30) * (dataSort && dataSort.length - (startSlice + visibleShips+1))
}
const getTopHeight = () => {
console.log(rowShips, startSlice)
return (rowShips + 30) * startSlice
}
// useEffect(() => {
// console.log(getTopHeight(), startSlice)
// }, [getTopHeight, startSlice]);
useEffect(() => {
function onScroll(e: any) {
setStartSlice(
Math.floor(e.target.scrollTop / (rowShips + 30))
);
}
rootRef.current && rootRef.current.addEventListener('scroll', onScroll);
return () => {
rootRef.current && rootRef.current.removeEventListener('scroll', onScroll);
}
}, [visibleShips, rowShips]);
const {
className,
children,
...otherProps
} = props
useEffect(() => {
if (data?.vehicles) {
setDataSort(data.vehicles)
}
}, [data]);
return (
<div
className={classNames("", {}, [className])}
style={{height: (rowShips + 30) * visibleShips, overflow: 'auto'}}
ref={rootRef}
{...otherProps}
>
<div className={cls.top} style={{height: getTopHeight()}}/>
<div className={cls.CardShip}>
{dataSort && dataSort.slice(startSlice, startSlice + visibleShips).map((vehicle: Vehicle, index: number) => (
<div className={cls.cardWrapper} style={{height: rowShips, margin: "30px"}}
key={startSlice + index}>
<div className={cls.title}>{vehicle.title}</div>
<img className={cls.flag} src={`https:${vehicle.nation.icons.large}`}/>
<img className={cls.ship} src={`https:${vehicle.icons.medium}`}/>
<div className={cls.type}>{vehicle.type.name}</div>
<div className={cls.nation}>{vehicle.nation.name}</div>
<div className={cls.level}>{vehicle.level}</div>
<div className={cls.description}>{vehicle.description}</div>
</div>
)
)}
</div>
<div style={{height: getBottomHeight(), width:"100vw"}}/>
</div>
);
});
Вот стили
.CardShip {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.top{
background-color: red;
width: 1000px;
}
.bottom{
width: 1000px;
}
.cardWrapper {
position: relative;
width: 440px;
overflow: hidden;
border: 3px solid white;
border-radius: 10px;
padding: 10px;
}
.ship {
z-index: 100;
position: inherit;
}
.flag {
width: 310px;
position: absolute;
top: 20px;
left: 70px;
opacity: 0.7;
}
.title {
font-family: var(--font-title);
font-size: 36px;
margin-top: 0;
line-height: 43px;
margin-bottom: 25px;
color: #b2b5ba;
text-transform: uppercase;
position: absolute;
top: 30px;
left: 80px;
}
.description {
font-family: var(--font-description);
color: #b2b5ba;
margin-top: 60px;
}
.type {
font-family: var(--font-title);
font-size: 36px;
margin-top: 0;
line-height: 43px;
margin-bottom: 25px;
color: #b2b5ba;
text-transform: uppercase;
position: absolute;
top: 270px;
left: 180px;
}
.nation {
font-family: var(--font-title);
font-size: 36px;
margin-top: 0;
line-height: 43px;
margin-bottom: 25px;
color: #b2b5ba;
text-transform: uppercase;
position: absolute;
top: 80px;
left: 80px;
}
.level {
font-family: var(--font-title);
font-size: 36px;
margin-top: 0;
line-height: 43px;
margin-bottom: 25px;
color: #b2b5ba;
text-transform: uppercase;
position: absolute;
top: 270px;
left: 80px;
}
Еще раз обращу внимание, что если отключить стили .CardShip то все работает плавно.