我想重新实现一个树组件以提高其性能。我从反应窗口使用了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
答案 0 :(得分:1)
要防止react-window
重新呈现列表中的每个项目,您需要:
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
没有任何关系,因此您可能要单独调试它,以弄清楚为什么您的变换没有设置动画,而其他属性设置了动画。