Skip to content

"NotFoundError: Failed to execute 'removeChild' on 'Node'" when using React.Fragment <></> with Chrome extension which does not modify the DOM tree below the root div of the React app #17256

Open
@tonix-tuft

Description

@tonix-tuft

This has already been discussed before (#14740), but there wasn't a reproducing example for this kind of issue and I think that my use case is also a bit different.

Do you want to request a feature or report a bug?
I believe this can be considered a bug.

What is the current behavior?
In order to reproduce this issue using Chrome, you will need to install the following Chrome extension called TransOver:

Screen Shot 2019-11-03 at 22 51 33

https://chrome.google.com/webstore/detail/transover/aggiiclaiamajehmlfpkjmlbadmkledi?hl=en

I use it to translate text on hover.
The only thing that this extension does is appending a tooltip with the translated text to the body HTML element when you hover an element with text (it doesn't seem it appends stuff below the React's root div element).

I have created two code sandboxes to show you better and explain the problem.
It is a minimal example of a movie app like the one Dan showed at JSConf 2018 in Iceland, though not as beautiful as his and without all that cool Suspense stuff, but at least it uses hooks :) .

The two code sandboxes are essentially identical, the only difference is that the first one (heuristic-lake-exxvu) uses a div element for MovieApp, whereas the second (magical-grass-016kc) uses a React.Fragment (<></>) component:

heuristic-lake-exxvu's MovieApp:

const MovieApp = () => {
  const [currentMovie, setCurrentMovie] = useState(initialCurrentMovieState);
  const { isLoading, id: currentMovieId, movieDetails } = currentMovie;
  ...
  return (
    <div> // <======================= Uses a `div`
      {isLoading ? (
        "Loading..."
      ) : (
      ...

magical-grass-016kc's MovieApp:

const MovieApp = () => {
  const [currentMovie, setCurrentMovie] = useState(initialCurrentMovieState);
  const { isLoading, id: currentMovieId, movieDetails } = currentMovie;
  ...
  return (
    <> // <======================= Uses a fragment
      {isLoading ? (
        "Loading..."
      ) : (
      ...

Now, if you open heuristic-lake-exxvu and click on the Show movie info button of any movie in the list, you will see the Loading... text before the promise with the data of the movie resolves, and the Movie component is rendered.

Before the promise resolves, try hovering on the Loading... text with the TransOver extension enabled, you should see:

Screen Shot 2019-11-03 at 23 26 48

The world makes sense here, no errors, no warnings, everything works.

Now try to do the same thing on magical-grass-016kc, as soon as you hover Loading..., you will see the NotFoundError: Failed to execute 'removeChild' on 'Node' error logged in the browser's console:

Screen Shot 2019-11-03 at 23 40 00

Screen Shot 2019-11-03 at 23 40 52

Here is a streamable video showing this same error:

https://streamable.com/4gxua

What is the expected behavior?
In heuristic-lake-exxvu (uses a div instead of React fragment), everything worked.
The TransOver extension appends to body and does not modify the React's root div neither does it append stuff below it, so I would expect the code in the React fragment example (magical-grass-016kc) to behave the same and work as in heuristic-lake-exxvu.

Chrome is plenty of useful extensions like this one and they should not really interfere with React, I think that users using React applications may also install other extensions which modify the DOM which they find useful.
If an extension appends to body like TransOver does, I wouldn't expect React to have problems with it and cause undesirable effects and application errors like this one.

This is my opinion, I would be very glad to hear what you think about it, and if you think I have spotted a bug of React fragments (I think it's a bug because, again, it works when using a div in heuristic-lake-exxvu).

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

Browser: Chrome
React v16.11.0
React DOM v16.11.0

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions