使用react-window

时间:2019-06-13 20:15:43

标签: reactjs react-window

我想重新实现一个树组件以提高其性能。我从反应窗口使用了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>

它也不起作用。 div不会更新,而是重新渲染整个div。是否有解决此问题的适当方法?如何防止重新渲染?

下面是整个示例:https://codesandbox.io/s/a-quick-react-tree-component-based-on-react-window-tyxnm

1 个答案:

答案 0 :(得分:1)

要防止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可能有一种更简单的方法,但我无法弄清楚。

如果使用Chrome开发人员工具检查DOM节点,则会看到在扩展一个节点时不再为整个树重新创建DOM节点。这样可以消除选择新节点时以前看到的闪烁(在Chrome中,但在Firefox中不是)。

但是还有其他一些因素阻止旋转动画正常工作。在上面链接的CodeSandbox示例中,我在border属性上添加了一些动画,以显示某些CSS属性的动画如何工作,而transform CSS属性的动画却不起作用。我怀疑这个问题与react-window没有任何关系,因此您可能要单独调试它,以弄清楚为什么您的变换没有设置动画,而其他属性设置了动画。