[英]ReactJS - Detect third-party DOM insert using Mutation Observer
Inside the component, a third-party JavaScript library has injected some content into a specific DIV ( voice-service
) after React render.在组件内部,第三方 JavaScript 库在 React 渲染后将一些内容注入到特定的 DIV(
voice-service
)中。 I wanted to add or remove some CSS class on that DIV ( voice-service
) when the DOM was injected using Mutation Observer, like -当使用 Mutation Observer 注入 DOM 时,我想在该 DIV(
voice-service
)上添加或删除一些 CSS 类,例如 -
When DOM injected -当 DOM 注入时 -
<div id="maxVoiceContainer" class="voice-service service--active">
// third-party content
</div>
When DOM Not injected -当 DOM 未注入时 -
<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 -想知道 -
Q: Do I need to disconnect the observer?问:我需要断开观察者的连接吗? It's not needed directly, but I recommand it with the
mutationObserver.disconnect()
Method, because you is called One time on ComponentDidMount.它不是直接需要的,但我推荐使用
mutationObserver.disconnect()
方法,因为你在 ComponentDidMount 上被调用一次。 An empty Array at the second parameter means it.第二个参数处的空数组表示它。 Ref
参考
Looks good?看起来不错? best practices?
最佳实践? Yes looks quite good.
是的,看起来不错。 Avoid nested forEach.
避免嵌套 forEach。 Better use first a map and than an forEach
最好先使用地图而不是 forEach
mutations.map(mutation => mutation.addedNodes).forEach(node => { if (node.classList && node.classList.contains('pocket-sphinx-container')) { setVoiceAvailability(status => !status); } });
Also, I do not want to re-render when the state was updated!另外,我不想在状态更新时重新渲染! React's lifecycle is build for this.
React 的生命周期就是为此而构建的。 There are two possibilities.
有两种可能。 First, you can use Redux or you make a local variable which is being setted in the forEach.
首先,您可以使用 Redux 或创建一个在 forEach 中设置的局部变量。 But generally don't use a setState hook in a forEach
但一般不要在 forEach 中使用 setState 钩子
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.