Предотвратить повторную визуализацию элемента DOM в компоненте виртуализированного дерева с использованием реагирующего окна

Я хочу повторно реализовать компонент дерева, чтобы улучшить его производительность. Я использовал FixedSizeList из реагирующего окна. Работает относительно хорошо. Он может обрабатывать даже 100000 узлов дерева.

Моя проблема в том, что я хочу анимировать маленький начальный треугольник узла дерева. Следующие css отвечают за анимацию:

.tree-branch::after {
  content: '';
  display: block;
  width: 0;
  height: 0;
  margin-top: 1px;
  margin-left: 23px;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-left: 6px solid rgba(0, 0, 0, 0.7);
  opacity: 0.7;
  position: absolute;
  top: 0;
  left: -36px;
  transform: rotate(90deg);
  animation-duration: 0.3s;
}

.tree-item-closed::after {
  transform: rotate(0deg);
}

Анимация не работает. Потому что при каждом открытии и закрытии всех элементов списка div-рендеринга. Затем я попытался добавить свойство itemKey для списка, чтобы помочь React повторно использовать элементы div.

    <List
      className="List"
      height={height}
      itemCount={flattenedData.length}
      itemSize={32}
      width={width}
      itemKey={index => flattenedData[index].id} // key defined
    >
      {Row}
    </List>

Это тоже не работает. DIVs не обновляются, вместо этого переопределяются все DIV. Есть ли правильное решение этой проблемы? Как я могу предотвратить повторный рендеринг?

Вот целый пример: https://codesandbox.io/s/a-quick-react-tree-component-based-on-react-window-tyxnm

1 ответ

Решение

Предотвращать react-window от повторного рендеринга каждого элемента в списке, вам необходимо:

  1. Запомните вашу функцию рендеринга строк
  2. Переместите эту функцию за пределы родительской функции.
  3. Использовать itemData prop для связи между родительским компонентом и функцией вывода для каждой строки.

Эта стратегия используется в примере с песочницей для окна реакции здесь: https://codesandbox.io/s/github/bvaughn/react-window/tree/master/website/sandboxes/memoized-list-items

Вот пример использования вашего кода: https://codesandbox.io/s/a-quick-react-tree-component-based-on-react-window-8psp0

Там может быть более простой способ сделать это с помощью useMemo но я не мог этого понять.

Если вы изучите DOM-узлы с помощью инструментов разработчика Chrome, вы увидите, что DOM-узлы больше не воссоздаются для всего дерева при расширении одного узла. Это устраняет мерцание, которое вы видели раньше (в Chrome, но не в Firefox) при выборе нового узла.

Но есть еще кое-что, что мешает вашей анимации вращения работать должным образом. В приведенном выше примере CodeSandbox я добавил несколько анимаций на border свойства, чтобы показать, как работает анимация некоторых свойств CSS, но анимация transform Свойства CSS не работают. Я подозреваю, что эта проблема не имеет ничего общего с react-windowтак что вы, вероятно, захотите отладить его отдельно, чтобы выяснить, почему ваши преобразования не анимируются, но другие свойства анимируются нормально.

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