Reactjs: Callback for DangerousNetworkInnerHTML completed
I currently have a React component:
<div id="product-content" className="bz">
<a className="anchor" id="content-anchor"></a>
<h2 className="title-section">Thông tin sản phẩm</h2>
<div className="fixed-menu-content">
<div className="container">
<ul>
<li><a href="#content-anchor">Thông tin sản phẩm</a></li>
<li><a href="javascript:void(0)">Video sản phẩm</a></li>
<li><a href="#rating-anchor">Đánh giá (19)</a></li>
<li><a href="#guide-anchor">Hướng dẫn mua hàng</a></li>
</ul>
</div>
</div>
<div dangerouslySetInnerHTML={{__html: description}}></div>
</div>
Seems to be dangerous SetInnerHTML does not affect component lifecycle. I put this line in componentDidMount but it returns the wrong result:
let b = $("#product-content").height(); // wrong: 600, true: 6500
If I try to run above in the dev console tool, it returns true because the component is fully rendered.
How can I call a callback for the dangerous SetInnerHTML?
source to share
There is no callback for completion dangerouslySetInnerHTML
, you have to resort to refs and DOMSubtreeModified .
// use ref to get the DOM Node
<div
dangerouslySetInnerHTML={{__html: description}}
ref={myElement => this.myElement = myElement}
>
</div>
// Listen for changes inside the DOM Node
componentDidMount() {
this.myElement.addEventListener('DOMSubtreeModified', () => {
// execute your logic here...
});
}
// Don't forget to clean up the listener
componentWillUnmount() {
this.myElement.removeEventListener('DOMSubtreeModified');
}
PS.
Be very careful with this event (DOMSubtreeModified), it's easy to call an infinite loop if you decide to modify the DOM inside an event handler.
source to share
It looks like the DOMSubtreeModified event has been deprecated in favor of the Mutation Observer API .
You can refactor the code suggested by lustoykov to use the new API:
class ContentRenderer extends React.Component {
componentDidMount() {
this.observer = new MutationObserver(this.handleMutation);
this.observer.observe(this.myElement, {
// Check config in https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
childList: true,
attributes: true,
characterData: true
});
}
componentWillUnmount() {
this.observer.disconnect();
}
handleMutation() {
console.log('mutation');
}
render() {
return (
<div
dangerouslySetInnerHTML={{ __html: "<div>Test</div>" }}
ref={(myElement) => { this.myElement = myElement; }}
/>
);
}
}
source to share