4

I want to re implement a tree component to improve its performance. I used the FixedSizeList from react-window. Its working relatively well. It can handle even 100,000 tree node.

My problem is, that I want to animate the little opening triangle of the tree node. The following css responsible for the animation:

.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);
}

The animation does not works. Because at each open and close all of the list element divs re-rendering. Then I tried to add itemKey property for the list to help React reusing the divs.

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

It does not work either. The divs are not updated instead the whole divs are re-rendered. Is there a proper solution for this problem? How can I prevent the re-rendering?

Here is the whole example: https://codesandbox.io/s/a-quick-react-tree-component-based-on-react-window-tyxnm

Peter Ambruzs
  • 7,763
  • 3
  • 30
  • 36

1 Answers1

8

To prevent react-window from re-rendering every item in the list, you need to:

  1. Memoize your row-rendering function
  2. Move that function outside the scope of the parent function
  3. Use the itemData prop to communicate between the parent component and per-row render function.

This is the strategy used in the react-window example sandbox here: https://codesandbox.io/s/github/bvaughn/react-window/tree/master/website/sandboxes/memoized-list-items

Here's an example using your code: https://codesandbox.io/s/a-quick-react-tree-component-based-on-react-window-8psp0

There may be a simpler way to do it using useMemo but I couldn't figure that out.

If you examine the DOM nodes using Chrome dev tools, you'll see that DOM nodes are no longer being re-created for the entire tree when one node is expanded. This removes the flicker that you'd see before (in Chrome, but not in Firefox) when selecting a new node.

But there's also something else that's preventing your rotation animations from working properly. In the CodeSandbox example I linked above, I added some animations on the border properties to show how animation of some CSS properties is working, but animation of the transform CSS properties is not working. I suspect this problem has nothing to do with react-window, so you'll probably want to debug it separately to figure out why your transforms aren't animating but other properties are animating OK.

Justin Grant
  • 44,807
  • 15
  • 124
  • 208
  • 2
    I read your conversation on [react-window github](https://github.com/bvaughn/react-window/issues/264#issuecomment-501865925) page. And based on that answer it seems that the memoization is good but not essential for preventing re render. I also fixed the animation, it was a CSS problem. This is the fixed version for reference: [codesandbox](https://codesandbox.io/s/t6w9g) Thank you for your help, it reminds me how great is this site. – Peter Ambruzs Jun 18 '19 at 08:47