Sobes.tech
Middle

Иҷрои рӯйхати виртуалӣ (Virtual List): рӯйхати дарозии паёмҳо вуҷуд дорад, ва бояд танҳо унсурҳои намоён дар дохили контейнер бо баландии доимии 300 пиксел рендер карда шаванд. Баландии як сатр 30 пиксел аст.

sobes.tech AI

Ҷавоб аз 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} />

В этом примере:

  • Внешний контейнер фиксированной высоты с прокруткой.
  • Внутренний блок имеет общую высоту всех элементов, чтобы скролл работал корректно.
  • Отрисовываются только видимые элементы с корректным смещением по вертикали.

Это значительно повышает производительность при работе с большими списками.