Назад к вопросам
Middle
4
Реализуй виртуальный список (Virtual List): есть длинный список сообщений, нужно рендерить только видимые элементы внутри контейнера с фиксированной высотой 300 пикселей. Высота одной строки — 30 пикселей.
Компании, где спрашивали
Basis
Ответ от нейросети
sobes.tech AI
Для реализации виртуального списка с фиксированной высотой контейнера 300px и высотой строки 30px нужно рендерить только те элементы, которые видны в данный момент, плюс небольшой запас для плавного скролла.
Количество видимых элементов: 300 / 30 = 10.
Пример на React с использованием хуков:
import React, { useState, useRef, useEffect } from 'react';
function VirtualList({ items }) {
const containerHeight = 300;
const rowHeight = 30;
const visibleCount = containerHeight / rowHeight;
const [scrollTop, setScrollTop] = useState(0);
const containerRef = useRef(null);
const startIndex = Math.floor(scrollTop / rowHeight);
const endIndex = Math.min(startIndex + visibleCount + 1, items.length);
const offsetY = startIndex * rowHeight;
const visibleItems = items.slice(startIndex, endIndex);
const onScroll = (e) => {
setScrollTop(e.currentTarget.scrollTop);
};
return (
<div
ref={containerRef}
onScroll={onScroll}
style={{ height: containerHeight, overflowY: 'auto', position: 'relative', border: '1px solid #ccc' }}
>
<div style={{ height: items.length * rowHeight, position: 'relative' }}>
<div style={{ transform: `translateY(${offsetY}px)`, position: 'absolute', top: 0, left: 0, right: 0 }}>
{visibleItems.map((item, index) => (
<div key={startIndex + index} style={{ height: rowHeight, borderBottom: '1px solid #eee', boxSizing: 'border-box', padding: '5px' }}>
{item}
</div>
))}
</div>
</div>
</div>
);
}
// Использование:
// const messages = Array.from({length: 1000}, (_, i) => `Сообщение ${i + 1}`);
// <VirtualList items={messages} />
В этом примере:
- Внешний контейнер фиксированной высоты с прокруткой.
- Внутренний блок имеет общую высоту всех элементов, чтобы скролл работал корректно.
- Отрисовываются только видимые элементы с корректным смещением по вертикали.
Это значительно повышает производительность при работе с большими списками.