Bug: Detached DOM nodes exist when component is unmounted

See original GitHub issue

I’ve written a simple React APP which contains 2 buttons, one is to increase the count number trigger the child component to create a table element with some random numbers, another is to toggle mount/unmount status of the child component.

I found that just a simply mount the component then unmount it which leaves detached DOM nodes in memory profiling. Following below steps:

  1. Click regen button
  2. Click toggle button

image

but if I mount and unmount the component again by adding 3, 4 steps below:

  1. Click regen button
  2. Click toggle button
  3. Click toggle button
  4. Click toggle button

In such orders, those detached DOM nodes will be cleaned. Is there any reason why those detached DOM nodes are not clear for the first time but distinguished by the second time the component is unmounted? image

React version: 17.0.2

Steps To Reproduce

  1. Click regen button
  2. Click toggle button

Link to code example: https://v6dhm.csb.app/

code attached:

import React, { useCallback, useMemo, useState } from "react";

const App = () => {
  const [count, setCount] = useState(0);
  const [display, setDisplay] = useState(true);

  const regen = useCallback(() => {
    setCount((e) => ++e);
  }, []);
  const toggle = useCallback(() => {
    setDisplay((e) => !e);
  }, []);

  return (
    <div>
      <button onClick={regen}>regen</button>
      <button onClick={toggle}>toggle</button>
      {display && <FTable count={count}></FTable>}
    </div>
  );
};
const Cell = () => {
  const num = Math.floor(Math.random() * 100);
  return <td>{num}</td>;
};

const FTable = (props) => {
  const { count } = props;
  const rows = useMemo(() => {
    const r = [];
    if (count == 0) {
      return r;
    }
    for (let i = 0; i < 1000; i++) {
      r.push(
        <tr key={`${i}-${count}`}>
          <Cell></Cell>
          <Cell></Cell>
          <Cell></Cell>
        </tr>
      );
    }
    return r;
  }, [count]);

  return (
    <div>
      <table>
        <tbody>{rows}</tbody>
      </table>
    </div>
  );
};

export default App;

The current behavior

Detached HTMLTable* are found in the devTool memory timeline

The expected behavior

No Detached DOMs are found in the devTool memory timeline

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

5reactions
snakepoongmailcommented, Feb 9, 2022

Hello @snakepoongmail,

is this causing you any troubles? I think this is a side effect of how React Fiber holds onto pieces of data and is harmless. The data will eventually be cleaned up.

Hello @sammy-SC , thx for your responding.

The issue now is I’m not quite sure about the timing when this data will be clean up. During the test, I’ve tried waiting for about 5 mins, clicking GC button in devTool, but it won’t help freeing those occupied memory.

Those Detached DOM elements should be considered as memory leak, in my application there are other detached DOM elements found held by React Fiber as well which means they are not able to be collected by GC, the size of the leak could be incrementing over time may end up crashing the application by consuming too many memory. Especially for building big and long running applications, memory leak is fatal for not being tackle well.

0reactions
TUTOR03commented, Dec 2, 2022

This seems to be a related issue to the one I posted recently: #25772 Maybe this will help to understand what’s going on.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Debug DOM memory leaks with the Detached Elements tool
A memory leak can occur in your application when an element is no longer attached to the Document Object Model (DOM) tree, but...
Read more >
javascript - If a DOM Element is removed, are its listeners also ...
According to the jquery Documentation when using remove() method over an element, all event listeners are removed from memory. This affects the element...
Read more >
Do Not Get Too Detached - Cypress
Element detached from the DOM error message. In this blog post I will go through a scenario showing this problem and show how...
Read more >
Can't perform a react state update on an unmounted component
Mounting is the process of adding a component that exists in the form of a Virtual DOM node in memory to the browser...
Read more >
An open source framework for finding JavaScript memory leaks
For example, the following export statement caches React components at the module scope level, so the associated Fiber tree and detached DOM ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found