[英]ReactJS - Detect third-party DOM insert using Mutation Observer
在组件内部,第三方 JavaScript 库在 React 渲染后将一些内容注入到特定的 DIV( voice-service
)中。 当使用 Mutation Observer 注入 DOM 时,我想在该 DIV( voice-service
)上添加或删除一些 CSS 类,例如 -
当 DOM 注入时 -
<div id="maxVoiceContainer" class="voice-service service--active">
// third-party content
</div>
当 DOM 未注入时 -
<div id="maxVoiceContainer" class="voice-service service--inactive">
// third-party content
</div>
英雄语音组件:
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;
想知道 -
问:我需要断开观察者的连接吗? 它不是直接需要的,但我推荐使用mutationObserver.disconnect()
方法,因为你在 ComponentDidMount 上被调用一次。 第二个参数处的空数组表示它。 参考
看起来不错? 最佳实践? 是的,看起来不错。 避免嵌套 forEach。 最好先使用地图而不是 forEach
mutations.map(mutation => mutation.addedNodes).forEach(node => { if (node.classList && node.classList.contains('pocket-sphinx-container')) { setVoiceAvailability(status => !status); } });
另外,我不想在状态更新时重新渲染! React 的生命周期就是为此而构建的。 有两种可能。 首先,您可以使用 Redux 或创建一个在 forEach 中设置的局部变量。 但一般不要在 forEach 中使用 setState 钩子
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.