在组件内部,第三方JavaScript库在render之后向特定的DIV (voice-service)注入了一些内容。当使用变异观察者注入DOM时,我想在DIV (voice-service)上添加或删除一些CSS类,比如-
当多姆被注射-
<div id="maxVoiceContainer" class="voice-service service--active">
// third-party content
</div>当多姆没有注射的时候-
<div id="maxVoiceContainer" class="voice-service service--inactive">
// third-party content
</div>heroVoice组件:
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;想知道-
发布于 2021-06-25 07:20:16
问:我需要断开观察者的联系吗?它不是直接需要的,但是我用方法重新推荐它,因为您在ComponentDidMount上只被调用了一次。第二个参数处的空Array表示它。参考
看上去不错吗?最佳做法?是的看起来挺好的。避免嵌套forEach。最好先使用地图,而不是使用forEach
mutations.map(mutation => mutation.addedNodes).forEach(node => {
if (node.classList && node.classList.contains('pocket-sphinx-container')) {
setVoiceAvailability(status => !status);
}
});
另外,我不想在状态更新时重新呈现!React的生命周期就是为此构建的。有两种可能性。首先,您可以使用Redux或者创建一个正在forEach中设置的局部变量。但是通常不要在setState中使用forEach钩子
https://stackoverflow.com/questions/68126486
复制相似问题