[英]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.