Предотвратить повторную визуализацию элемента DOM в компоненте виртуализированного дерева с использованием реагирующего окна - PullRequest
0 голосов
/ 13 июня 2019

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

Моя проблема в том, что я хочу анимировать маленький начальный треугольник узла дерева. Следующие 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 Ответ

1 голос
/ 18 июня 2019

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

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

Эта стратегия используется в примере с песочницей в окне реагирования здесь: 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, поэтому вы, вероятно, захотите отладить ее отдельно, чтобы выяснить, почему ваши преобразования не анимируются, но другие свойства анимируются нормально.

...