首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ReactJS -使用变异观察者检测第三方DOM插入

ReactJS -使用变异观察者检测第三方DOM插入
EN

Stack Overflow用户
提问于 2021-06-25 06:35:29
回答 1查看 992关注 0票数 3

在组件内部,第三方JavaScript库在render之后向特定的DIV (voice-service)注入了一些内容。当使用变异观察者注入DOM时,我想在DIV (voice-service)上添加或删除一些CSS类,比如-

当多姆被注射-

代码语言:javascript
复制
<div id="maxVoiceContainer" class="voice-service service--active">
 // third-party content
</div>

当多姆没有注射的时候-

代码语言:javascript
复制
<div id="maxVoiceContainer" class="voice-service service--inactive">
// third-party content
</div>

heroVoice组件:

代码语言:javascript
复制
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;

想知道-

  1. 我需要断开观察者的连接吗?
  2. 看上去不错吗?最佳做法?
  3. 另外,我不想在状态更新时重新呈现!
EN

回答 1

Stack Overflow用户

发布于 2021-06-25 07:20:16

问:我需要断开观察者的联系吗?它不是直接需要的,但是我用方法重新推荐它,因为您在ComponentDidMount上只被调用了一次。第二个参数处的空Array表示它。参考

看上去不错吗?最佳做法?是的看起来挺好的。避免嵌套forEach。最好先使用地图,而不是使用forEach

代码语言:javascript
复制
 mutations.map(mutation => mutation.addedNodes).forEach(node => {
  if (node.classList && node.classList.contains('pocket-sphinx-container')) {
    setVoiceAvailability(status => !status);
  }
 });

另外,我不想在状态更新时重新呈现!React的生命周期就是为此构建的。有两种可能性。首先,您可以使用Redux或者创建一个正在forEach中设置的局部变量。但是通常不要在setState中使用forEach钩子

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68126486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档