Использование response-sortable-hoc с MultiGrid реагирующей виртуализации

Я хочу использовать response-sortable -hoc с MultiGrid реагирующей виртуализации. Более конкретно, я хотел бы иметь возможность сортировать строки в нижней правой сетке.

1-я попытка

Я создаю SortableMultiGrid с помощью

const SortableMultiGrid = SortableContainer(MultiGrid, {
  withRef: true,
});

Но когда это монтируется, я получаю сообщение об ошибке, с этим сообщением

Не удается прочитать свойство 'ownerDocument' из неопределенного

Ошибка происходит от SortableContainer Метод componentDidMount.

2-я попытка

Я обнаружил, что SortableContainer имеет getContainer свойство, которое вызывается чуть выше кода, который выдает ошибку:

Необязательная функция для возврата прокручиваемого элемента контейнера. По умолчанию это свойство относится к самому элементу SortableContainer или (если true для useWindowAsScrollContainer) окна. Используйте эту функцию, чтобы указать пользовательский контейнерный объект (например, это полезно для интеграции с некоторыми сторонними компонентами, такими как FlexTable). Этой функции передается единственный параметр (элемент React wrappedInstance), и ожидается, что он вернет элемент DOM.

Он вызывается с экземпляром компонента MultiGrid, но когда я пытаюсь получить от него узел DOM, он возвращает null:

getContainer={e => {
  const multiGrid = ReactDOM.findDOMNode(e);
  // multiGrid is null - I must return an HTMLElement
}}

Я подозреваю, что это может быть вызвано тем, что компонент MultiGrid еще не смонтирован, и я подозреваю, что то, что я вижу, связано с https://github.com/clauderic/react-sortable-hoc/issues/135.

3-я попытка - работает, но это взлом

Я подумал, что, возможно, смогу обмануть SortableContainer, вернув сначала что-то, что не вызовет ошибку, а затем, когда можно будет определить ссылку на нижнюю правую сетку внутри многосетки, я мог бы снова вызвать componentDidMount из SortableContainer.

<SortableMultiGrid
  // ...
  ref={sortableGrid => {
    if (sortableGrid) {
      const multiGrid = sortableGrid.getWrappedInstance();
      if (multiGrid && multiGrid._bottomRightGrid) {
        const bottomRightGrid = multiGrid._bottomRightGrid;
        const bottomRightGridNode = ReactDOM.findDOMNode(
          bottomRightGrid
        );
        this.bottomRightGrid = bottomRightGridNode;
        // HACK: We shouldn't ever call componentDidMount on components
        sortableGrid.componentDidMount();
      }
    }
  }}
  getContainer={e => {
    if (this.bottomRightGrid) {
      return this.bottomRightGrid;
    } else {
      // If its unknown - return something that wont throw errors
      return {
        ownerDocument: document,
        addEventListener: () => { },
        removeEventListener: () => { }
      };
    }
  }}
/>

Это на самом деле, кажется, работает! Но я все еще хотел бы знать, есть ли у кого-нибудь идеи о том, как этого можно достичь с большей элегантностью, или как следует изменить одну из двух библиотек, чтобы решить эту проблему.


CodeSandbox

Я сделал две песочницы, чтобы проиллюстрировать это:

  1. Первый - это функциональная сортируемая сетка (я не реализовал сохранение конечного состояния): https://codesandbox.io/s/710kxo247x. Я реализовал "rowRangeRenderer", который отображает строки ячеек (обратите внимание, что он не полностью оптимизирован с кэшированием при прокрутке), чтобы заменить defaultCellRangeRenderer и разрешить перенос строк на HOC SortableElement.
  2. Это попытка использовать MultiGrid вместо Grid, которая показывает ошибку, упомянутую выше: https://codesandbox.io/s/1z390ow44
  3. Третья попытка - это вроде работает, но это взломать https://codesandbox.io/s/pprwo6m350

1 ответ

Хотя прошло 3 года, но недавно у меня было такое же требование, и я обнаружил, что это действительно полезно, я использую ReactDOM.findDOMNode(this)как контейнер, и он работает. https://codesandbox.io/s/sortable-multigrid-hacked-forked-3mj8e?file=/MySortableMultiGrid.js

Другие вопросы по тегам