facebook / react

The library for web and native user interfaces.
https://react.dev
MIT License
229.56k stars 47k forks source link

Bug: Uncaught runtime error with 'removeChild' and long lists #31281

Open Kevlanche opened 1 month ago

Kevlanche commented 1 month ago

React version: 18.3.1

Steps To Reproduce

  1. $ npx create-react-app my-app
  2. $ cd my-app
  3. Replace the contents of App.js with the code listed below
  4. $ npm run start
  5. Open the page in Google Chrome or Edge (issue does not reproduce in Firefox/Safari)
  6. Click one of the "x" labels
  7. Click "hide"
// App.js
import { useState } from 'react';

function App() {
  const [show, setShow] = useState(false);
  return (
    <div>
      {Array(950).fill().map(() => <span onClick={() => setShow(true)} key={`rng_${Math.random()}`}>x</span>)}
      <div>
        {show && (
          <div>
            <button onClick={() => setShow(false)}>Hide</button>
          </div>
        )}
      </div>
    </div>
  );
}

export default App;

Link to code example: https://codesandbox.io/p/sandbox/sleepy-resonance-29sgks

The current behavior

It fails with "Failed to execute 'removeChild on 'Node': [..]" This error message typically indicates that somebody or something has manipulated the DOM outside of React. However, as you can see in the very small reproducible example, this should not be the case.

I am able to reliably reproduce this on Google Chrome, but not Safari or Firefox. I tested on two different computers (both running OSX). I could reproduce with a project set up with three separate environments; using vite, create-react-app, and inside codesandbox. I also tried downgrading to react 17.0.2, and same problem there.

If the size of the list is reduced, the crash either stops or does not happen as often.

The expected behavior

I should be able to re-render components based on state.

adi-ydv-1 commented 1 month ago

880 is the limit..

Kevlanche commented 1 month ago

Thanks for reproducing the issue @adi-ydv-1!

I think the limit depends on your specific computer/browser. For me, it consistently reproduces on 950. A colleague of mine cannot get it to consistently reproduce there however, they have to set the size even higher. Considering it only seems to happen in chromium-based browser, maybe the issue is not with React itself, but with how chromium handles a long list of elements. Some kind of race condition? 🤔

adi-ydv-1 commented 5 days ago

then i think its the more of a problem of a web browser then react so try to use the one on which it works fine... @Kevlanche