Перейти к содержимому
v2.5.0
English
Русский
Документация

IndexedSnapScroller

IndexedSnapScroller — составной компонент на основе SnapScroller для виртуализированного постраничного пролистывания по окну индексов.

Паттерны

Контролируемый виртуальный индекс

Когда использовать:

  • логический индекс страницы должен оставаться синхронизированным с внешним интерфейсом, например с числовыми элементами управления

Заметки о композиции:

  • управляйте и внешним элементом, и скроллером из одного состояния индекса
  • пусть onScrollSnapChanging или onScrollSnapChange обновляют это состояние

Компромиссы:

  • явная синхронизация
  • больше движущихся частей, чем у неконтролируемого скроллера
controlled-virtual-index.tsx · 89 строк
import {
  Button,
  Icon,
  IconButton,
  IndexedSnapScroller,
  IndexedSnapScrollerContent,
  Text,
  useIndexedSnapScrollerContext,
  type IndexedSnapScrollerApiRef,
} from '@vega-ui/react';
import { ChevronLeft, ChevronRight } from '@vega-ui/icons';
import { useRef, useState } from 'react';

Окно виртуальной ленты

Когда использовать:

  • видимый набор страниц должен сдвигаться, когда пользователь движется вперёд или назад

Заметки о композиции:

  • настройте size, shift и start
  • содержимое страниц должно быть устойчивым к смене логических индексов

Компромиссы:

  • масштабируется
  • сложнее для понимания, чем фиксированный список страниц
lazy-page-data.tsx · 81 строка
import {
  IndexedSnapScroller,
  IndexedSnapScrollerContent,
  Text,
  useIndexedSnapScrollerContext,
} from '@vega-ui/react';
import { useCallback, useEffect, useRef, useState } from 'react';

const today = new Date();
const dayFormat = new Intl.DateTimeFormat('en-US', { weekday: 'long', month: 'short', day: 'numeric' });
const moneyFormat = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });

Низкоуровневое пролистывание календаря или ленты

Когда использовать:

  • другой подсистеме нужна виртуальная индексация страниц, но обёртки для предметной области ещё нет

Заметки о композиции:

  • держите логику предметной области вне скроллера
  • используйте предоставляемый контекст индекса при рендере содержимого

Компромиссы:

  • переиспользуемая основа
  • легко переусложнить, если обёртка более высокого уровня уже существует
week-strip.tsx · 64 строки
import {
  IndexedSnapScroller,
  IndexedSnapScrollerContent,
  Text,
  useIndexedSnapScrollerContext,
} from '@vega-ui/react';
import type { CSSProperties } from 'react';

const today = new Date();
const daysSinceMonday = (today.getDay() + 6) % 7;
const weekdayFormat = new Intl.DateTimeFormat('en-US', { weekday: 'short' });
const weekFormat = new Intl.DateTimeFormat('en-US', { month: 'long', day: 'numeric' });

Сравнение

Быстрое правило выбора

Используйте IndexedSnapScroller, когда пролистывание должно управляться логическим, возможно неограниченным индексом. Используйте SnapScroller, когда набор страниц уже стабилен и задан явно.

IndexedSnapScroller или SnapScroller

  • Используйте IndexedSnapScroller для сдвигающихся логических окон.
  • Используйте SnapScroller для страниц, заданных напрямую с ключами.

IndexedSnapScroller или DayPickerScroller / YearPickerScroller

  • Используйте IndexedSnapScroller как низкоуровневый примитив пролистывания по индексам.
  • Используйте скроллеры пикеров, когда предметная область — уже календарное пролистывание.

Выбирайте этот компонент, когда

  • содержимое лучше всего описывается виртуальной последовательностью индексов
  • окно страниц должно сдвигаться, когда пользователь приближается к границам

Не выбирайте этот компонент, когда

  • достаточно фиксированного набора страниц
  • больше подходят обёртки пролистывания, специфичные для календаря

Решение проблем

Видимая страница прыгает после достижения края

Симптом

Скроллер доходит до границы, и видимое содержимое будто прыгает.

Вероятная причина

Виртуальное окно сдвинулось, а позиция прокрутки не сохранилась, как ожидалось.

Как проверить

  • проверьте preserveScroll
  • посмотрите, вызывает ли смещение на границе сброс окна или добавление страниц в начало или конец

Исправление

Оставьте preserveScroll включённым, если ожидается сохранение текущей привязки.

Контролируемый index и видимое содержимое расходятся

Симптом

Родитель считает активным один индекс, а видимое содержимое страницы указывает на другой.

Вероятная причина

Обновления контролируемого индекса и внутренние сбросы окна не согласованы.

Как проверить

  • выведите в лог контролируемый index
  • сравните его с зафиксированным или ожидающим индексом привязки

Исправление

Используйте один явный источник истины и пусть родитель единообразно реагирует на колбэки привязки.

Состояние страницы протекает между разными логическими индексами

Симптом

При смене виртуального индекса содержимое будто переиспользует устаревшее состояние.

Вероятная причина

Шаблон содержимого рассчитывал на фиксированную идентичность вместо идентичности для каждого индекса.

Как проверить

  • изучите ключи дочерних элементов и логику состояния внутри шаблона содержимого

Исправление

Сделайте состояние для каждого индекса явным и не предполагайте, что одна физическая страница DOM навсегда равна одной логической странице.