React Domexception: Failed to Execute 'Removechild' on 'Node': the Node to Be Removed Is Not a Child of This Node
If State Is True to Play Youtube Video, and It Is False I Would Like to Delete Youtube Playing. My Code Is as Follows. {This. State. isPreViewVideo && }...
If state is true to play youtube video, and it is false I would like to delete youtube playing. MY code is as follows.
{this.state.isPreViewVideo && <PlayYouTube video_id="ScSn235gQx0" />}
sandbox URL:
Reproduction method:
If 4-digit characters are included in input form, "isPreViewVideo: true" by setState and if it is less than false
It works fine when state is true, but when state is false, I encounter this error as follows.
DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
is there a way to avoid or resolve this error?
14 Answers
In playYouTube.tsx line 78 replace <React.Fragment>...</React.Fragment>
with <div>...</div>
Fragments let you group a list of children without adding extra nodes to the DOM.
This explains the error
Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
More on fragments here
This error, Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node, can also be raised if Google Translate is used (or any other plugin that changes the page DOM).
This is detailed in this Github issue:
Problem explanation:
When isPreViewVideo is truthy, you have this:
<PlayYouTube video_id="ScSn235gQx0" />
That probably renders to something like this:
<div> <!-- the root element as rendered by PlayYouTube if isPreViewVideo is truthy -->
<embed /> <!-- the video player or whatever PlayYouTube renders -->
</div>
Now if some code removes the player by directly manipulating the DOM and removing the root div, you'll end up with... Well, with nothing.
But in React's virtual DOM, the root div still exists! So when isPreViewVideo goes falsy, React tries to remove it from the real DOM but since it's already gone, the error is thrown.
The solution:
To expand on @henrik123's answer - wrapping PlayYouTube with a div like this...
<div> <!-- the root element rendered if isPreViewVideo is truthy -->
<PlayYouTube video_id="ScSn235gQx0" />
</div>
...causes this to render:
<div> <!-- the root element rendered if isPreViewVideo is truthy -->
<div> <!-- the element as rendered by PlayYouTube -->
<embed /> <!-- the video player or whatever PlayYouTube renders -->
</div>
</div>
Now the same code that removes the player by removing its root div makes it look like this:
<div> <!-- the root element rendered if isPreViewVideo is truthy -->
</div>
Now when isPreViewVideo goes falsy, the root exists both in React's virtual DOM and in the real DOM so there is no problem in removing it. It's children have changed but React doesn't care in this case - it just needs to remove the root.
Note:
Other HTML elements but div may work too.
Note 2:
Wrapping with React.Fragment instead of a div would not work because React.Fragment doesn't add anything to the real DOM. So with this...
<React.Fragment>
<PlayYouTube video_id="ScSn235gQx0" />
</React.Fragment>
...you still end up with this:
<div> <!-- the root element as rendered by PlayYouTube if isPreViewVideo is truthy -->
<embed /> <!-- the video player or whatever PlayYouTube renders -->
</div>
And you have the same issue.
TL;DR solution:
Wrap PlayYouTube with a div.
SOLVED for bootstrap alert after manually close button
I had exact error when i close the bootstrap alert error message if it's there manually and then submit the form again. what i had done is to wrap up the AlertError component with extra tag around.
import React from "react";
const AlertError = (props) => {
return (
<div> // <---- Added this
<div className="alert alert-custom alert-notice alert-light-danger fade show" role="alert">
<div className="alert-icon"><i className="flaticon-warning"></i></div>
<div className="alert-text">There is an error in the form..!</div>
<div className="alert-close">
<button type="button" className="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true"><i className="ki ki-close"></i></span>
</button>
</div>
</div>
</div> // <---- Added this
);
};
export default AlertError;
This error can occur when you use external JS or jQuery plugins. Let me tell about my case.
Must Read
Issue description
In my React project I have some links on a page, every link opens a modal with some info and a slider with images inside it. Every link has its own set of images inside the slider. But I have the single modal, it is the same for every link. Data for modal is stored in a state variable and I change its content on every link click (on every modal open):
const initialData = { title: "", intro: "" }; // here is some empty structure of object properties, we need it for the modalResponse initialization
const [modalData, setModalData] = useState(initialData);
// ...
<div id="MyModal">
<div className="title">{modalData.title}</div>
<div className="intro">{modalData.intro}</div>
<div>{modalData.sliderHtml}</div>
</div>
When I open modal using setModalData() I fill modalData with some new data. HTML-code inside modalData.sliderHtml is something like this structure:
<div class="carousel">
<div class="item"><img src="first.jpg" /></div>
<div class="item"><img src="second.jpg" /></div>
<div class="item"><img src="third.jpg" /></div>
</div>
When modal has opened I call some jQuery code for slider initialization:
useEffect(() => {
$('.carousel').initCarousel({
// some options
});
}, [modalData]);
Then user could close the modal and click the next link. The slider must be filled by new set of images. But I get the error: Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.