Бесконечная загрузка с реагирующей таблицей + реагирующая виртуализация / реагирующее окно

avatar
Alex Tarasenko
19 апреля 2021 в 12:15
2592
1
12

У меня есть следующие требования к моей таблице:

  1. Таблица должна иметь фиксированный заголовок
  2. Необходим автоматический размер: чтобы работала бесконечная прокрутка, первая выборка должна получить достаточное количество данных, чтобы прокрутка вообще появилась.
  3. тело таблицы должно работать как бесконечный загрузчик: при прокрутке до конца списка тело таблицы должно отображать индикатор загрузки и загружать больше строк

Мои предположения следующие:

  1. поскольку пользователь будет прокручивать, возможно, большие наборы данных, я должен виртуализировать списки (мне кажется, что единственным хорошим вариантом является реактивная виртуализация)
  2. поскольку в настоящее время у нас есть реагирующая таблица, я хочу ее сохранить (у нее отличный механизм объявления строк таблицы, столбцов, доступа к данным и фильтрации + сортировки)
  3. Поскольку мы используем материал пользовательского интерфейса, мне нужно использовать компоненты материала пользовательского интерфейса
  4. Поскольку у react-virtualized есть собственный компонент Table, я мог бы его использовать, но у react-table другой способ рендеринга строк и столбцов, поэтому я должен использовать компонент List. (React-table разделяет строки и столбцы, в то время как react-virtualized использует столбцы непосредственно как дочерние элементы компонента Table)
  5. Я видел, что react-virtualized работает с компонентом HOC под названием InfiniteLoader, поэтому я должен использовать и его
  6. Наконец, мне нужно, чтобы мои столбцы не перепутались только потому, что в них больше текста (т.е. они имеют динамическую высоту). Поэтому я попытался использовать для этого CellMeasurer.

То, чего мне удалось достичь, можно увидеть в этой песочнице. https://codesandbox.io/s/react-table-infinite-mzkkp?file=/src/MuiTable.js (здесь я не могу предоставить код, потому что он довольно большой)

Итак, в общем, я мог сделать компоненты Autosizer, CellMeasurer и List из реактивной виртуализации для работы. Я застрял в бесконечной части прокрутки. Я видел пример в официальных документах, но он кажется немного противоречащим шаблону (состояние мутации — это вообще нехорошо)

Поэтому я пытался добиться аналогичного результата, однако, если вы могли видеть, моя функция loadMore по какой-то причине срабатывает слишком рано. Это приводит к тому, что запросы отправляются почти при каждом событии прокрутки.

Мы очень ценим любую помощь.

Что я уже пробовал:

  1. Использование окна реакции вместо виртуализированной реакции Он работает только для простых случаев использования и не работает с динамическим размером ячеек.
  2. Использование react-inifnite-scrollcomponent (https://www.npmjs.com/package/react-infinite-scroll-component) Он работает для всей страницы (невозможно сделать «липкий» заголовок, невозможно отображать индикаторы загрузки как часть тела таблицы, у него нет оптимизации для длинных списков)
  3. Использование компонента Table из react-virtualized. Мне не удалось заставить его работать с реагирующей таблицей (поскольку компонент таблицы из реагирующей виртуализации, похоже, отображает ячейки непосредственно как дочерние элементы компонента таблицы. Я знаю, что у него есть функция renderRow, но это означает два отдельных места, в то время как реагирующая таблица имеет
<TableRow
  {...row.getRowProps({
     style
  })}
  component="div"
  >
  {row.cells.map((cell) => {
     return (
       <TableCell {...cell.getCellProps()} component="div">
         {cell.render("Cell")}
       </TableCell>
      );
   })}
</TableRow>

Кроме того, непонятно, как таким образом отображать пользовательские фильтры.

Источник
Matan Gubkin
20 января 2022 в 18:21
0

Вы нашли решение?

Ответы (1)

avatar
Jeremy Gottfried
24 февраля 2022 в 00:30
0

Я знаю, что это не тот ответ, который вы искали, но я рекомендую использовать IntersectionObserver вместо библиотеки виртуализации. react-virtualized не подходит для динамических/отзывчивых элементов. IntersectionObserver — это собственный API-интерфейс браузера, который может определять, когда элемент входит в область просмотра, не предоставляя ему размеры элементов.

Вы можете легко использовать его с библиотекой реагирования, такой как react-intersection-observer, которая имеет компонент InView и хук useInView, хотя для этого потребуется обернуть каждую ячейку таблицы InView . Производительность IntersectionObserver, как правило, лучше, чем решение на основе событий прокрутки, такое как react-virtualized, хотя оно может ухудшиться, если у вас есть тысячи наблюдателей.

Вы также можете использовать что-то вроде intersection-observer-admin, что объединит всех ваших наблюдателей в один экземпляр, аналогичный react SyntheticEvent. Вы хотели бы интегрировать это во что-то вроде React.useContext или redux.