簡體   English   中英

ReactJS - 使用 Mutation Observer 檢測第三方 DOM 插入

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

想知道 -

  1. 我需要斷開觀察者的連接嗎?
  2. 看起來不錯? 最佳實踐?
  3. 另外,我不想在狀態更新時重新渲染!

問:我需要斷開觀察者的連接嗎? 它不是直接需要的,但我推薦使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM