title: React: Prevent large tree structure for re-rendering children
body: <p>I have a tree/directory structured data with around 14k nodes.
  I want to prevent all children of the tree from re-rendering since it takes a bit too long. A node can be expanded and minimized when clicking a button, which adds the id of the node to an <code>expanded</code> <code>Set</code> saved in Redux state. Currently, when adding a category to the Set the entire tree is re-rendered. How would I prevent this?</p>
  <p>The data structure:</p>
  <pre class="lang-json prettyprint-override"><code>[
    {
      &quot;id&quot;: &quot;1&quot;,
      &quot;name&quot;: &quot;Category 1&quot;,
      &quot;children&quot;: [
        {
          &quot;id&quot;: &quot;11&quot;,
          &quot;name&quot;: &quot;Category 1-1&quot;,
          &quot;children&quot;: []
        }
      ]
    },
    {
      &quot;id&quot;: &quot;2&quot;,
      &quot;name&quot;: &quot;Category 2&quot;,
      &quot;children&quot;: [
        {
          &quot;id&quot;: &quot;3&quot;,
          &quot;name&quot;: &quot;Category 2-1&quot;,
          &quot;children&quot;: [
            ...children
          ]
        }
      ]
    }
    ... and so forth
  ]
  
  
  </code></pre>
  <p>I have a recursive <code>TreeTableBranch</code> component which renders its children recursively:</p>
  <pre><code>const TreeTableBranch: React.FC&lt;Props&gt; = ({
   node,
   level,
   onExpand
  }) =&gt; {
    const expanded = useSelector((state: AppState) =&gt; state.categories.expanded);
    const shouldExpand = expanded.has(node.category.id);
    return (
      ...lots of divs for rendering a node
        &lt;button onClick={onExpand}&gt;Expand&lt;Button/&gt; 
         { shouldExpand &amp;&amp;
         node.children.map((v,i) =&gt; (
         &lt;TreeTableBranch
            key={v.category.id}
            node={v}
            level={level + 1}
            onExpand={onExpand}
          /&gt;
       )}
    )
  }
  
  </code></pre>
  <p>However, since the <code>expanded</code> list is modified, all children get re-rendered. I've tried to use <code>useMemo()</code> as follows:</p>
  <pre><code>const children = useMemo(() =&gt; {
      return (
        shouldExpand &amp;&amp;
        node.children.map((v, i) =&gt; (
          &lt;TreeTableBranch
            key={`category-branch-${v.category.id}`}
            node={v}
            level={level + 1}
            onExpand={onExpand}
            onAddCategory={onAddCategory}
            onDeleteCategory={onDeleteCategory}
          /&gt;
        ))
      );
    }, [shouldExpand]);
  
  </code></pre>
  <p>However this does not work, probably because the <code>expanded</code> list is modified.</p>
  <p>I've also tried to use <code>React.memo()</code> like this:</p>
  <pre><code>const areEqual = (prevProps: Props, nextProps: Props) =&gt; {
    return prevProps.shouldExpand === nextProps.shouldExpand;
  };
  </code></pre>
  <p>But it does not stop the other children from re-rendering.</p>
  <p>Any help or tips are appreciated!</p>