We're using React-smooth-scrollbar in an auto-complete dropdown, and as such, the content of the dropdown changes as the user types.
The suggestions are grouped together as a list of panels (which itself isn't important), and is rendered as follows:
<Scrollbar> {panels} </Scrollbar>
The issue arise when we remove a panel from the list, and React throws the following exception:
Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
at removeChild (webpack:///./~/react-dom/lib/DOMChildrenOperations.js?:65:14)
at Object.processUpdates (webpack:///./~/react-dom/lib/DOMChildrenOperations.js?:209:11)
at Object.dangerouslyProcessChildrenUpdates [as processChildrenUpdates] (webpack:///./~/react-dom/lib/ReactDOMIDOperations.js?:29:27)
at processQueue (webpack:///./~/react-dom/lib/ReactMultiChild.js?:137:29)
at ReactDOMComponent._updateChildren (webpack:///./~/react-dom/lib/ReactMultiChild.js?:355:9)
at ReactDOMComponent.updateChildren (webpack:///./~/react-dom/lib/ReactMultiChild.js?:299:12)
at ReactDOMComponent._updateDOMChildren (webpack:///./~/react-dom/lib/ReactDOMComponent.js?:930:12)
at ReactDOMComponent.updateComponent (webpack:///./~/react-dom/lib/ReactDOMComponent.js?:748:10)
at ReactDOMComponent.receiveComponent (webpack:///./~/react-dom/lib/ReactDOMComponent.js?:710:10)
at Object.receiveComponent (webpack:///./~/react-dom/lib/ReactReconciler.js?:125:22)
The cause of this appears to be DOM manipulation by the smooth-scrollbar package: https://github.com/idiotWu/smooth-scrollbar/blob/develop/src/index.js#L91
By changing the innerHTML, it causes a mismatch between reacts virtual DOM and the actual DOM, causing React to throw the above exception.
More specifically, when we remove a panel from the list, React calculates the changes using the virtual DOM and attempts to remove the child node. However, because the smooth-scrollbar library wraps the scrollable content in <article class="scroll-content"></article>
, the virtual DOM and actual DOM differ.
React calculated the changes to the DOM believing it to be:
<section data-scrollbar ref="container">
<child elements>
</section>
However due to manipulation by smooth-scroll bar, the actual DOM is:
<section data-scrollbar ref="container">
<article class="scroll-content">
<child elements>
</article>
</section>
The best fix for this might be preventing the DOM manipulation by the smooth-scroll library and instead modify the DOM through react-smooth-scroll? I'm not sure if there's a easier fix that leaves react-smooth-scrollbar as a wrapper but I'd be delighted to be proven wrong.