Inside the component, a third-party JavaScript library has injected some content into a specific DIV (voice-service) after React render. I wanted to add or remove some CSS class on that DIV (voice-service) when the DOM was injected using Mutation Observer, like -
When DOM injected -
<div id="maxVoiceContainer" class="voice-service service--active">
// third-party content
</div>
When DOM Not injected -
<div id="maxVoiceContainer" class="voice-service service--inactive">
// third-party content
</div>
heroVoice Component:
import React, { useRef, useState, useEffect } from 'react';
const heroVoice = (props) => {
const elementRef = useRef();
const [voiceAvailability, setVoiceAvailability] = useState(false);
useEffect(() => {
const config = { attributes: false, characterData: false, childList: true, subtree: true, attributeOldValue: false, characterDataOldValue: false };
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
const newNodes = mutation.addedNodes;
newNodes.forEach(node => {
if (node.classList && node.classList.contains('pocket-sphinx-container')) {
setVoiceAvailability(status => !status);
}
});
});
});
observer.observe(elementRef.current, config);
}, []);
return (
<div
ref={elementRef}
id="maxVoiceContainer"
className={`voice-service ${voiceAvailability ? ' service--active' : 'service--inactive'}`}
>
// third-party content
</div>
);
}
export default heroVoice;
Wanted to know -
- Do I need to disconnect the observer?
- Looks good? best practices?
- Also, I do not want to re-render when the state was updated!