简体   繁体   English

将元素添加到 DOM 时的反应性

[英]Reactivity when element added to DOM

I want to integrate qr-scanner to my project.我想将qr-scanner集成到我的项目中。 This library is capable of decoding QR-Codes by utilizing the camera.该库能够利用摄像头解码 QR 码。 It just needs the reference to a html-video-element and then renders the webcam-stream and optionally some indicators of a QR-code being found to this element.它只需要对 html-video-element 的引用,然后将网络摄像头流和可选的 QR 码的一些指示符呈现给该元素。

The easiest component would be something like this:最简单的组件是这样的:

import { useRef } from "react";
import QrScanner from "qr-scanner";

export const QrComponent = () => {
  const videoElement = useRef(null);
  const scanner = new QrScanner(videoElement.current, (result) => {
    console.log(result)
  }) 

  return (
    <video ref={videoElement} />
  )
}

however, qr-scanner checks, if the passed target-element is already part of the DOM :但是,qr-scanner 会检查传递的目标元素是否已经是 DOM 的一部分

if (!document.body.contains(video)) {
    document.body.appendChild(video);
    shouldHideVideo = true;
}

the video-element will never be added to the DOM, when the QrScanner-object is created.创建 QrScanner 对象时,视频元素将永远不会添加到 DOM。 This leads to shouldHideVideo being set to true, which disables the video altogether later in the library-code.这导致shouldHideVideo设置为 true,这会在库代码中完全禁用视频。

So I think I need some kind of way to react to the video-element being added to the DOM.所以我认为我需要某种方式来对添加到 DOM 的视频元素做出反应。 I thougt about using a MutationObserver (and tried it out by stealing the hook from this page ), however I only wanted to print out all mutations using the hook like this:我想使用 MutationObserver (并通过从这个页面窃取钩子来尝试它),但是我只想使用这样的钩子打印出所有突变:

import { useRef, useCallback } from "react";
import QrScanner from "qr-scanner";
import { useMutationObservable } from "./useMutationObservable";

export const QrComponent = () => {
  const videoElement = useRef(null);
  const scanner = new QrScanner(videoElement.current, (result) => {
    console.log(result)
  })

  const onMutation = useCallback((mutations) => console.log(mutations), [])
  useMutationObservable(document, onMutation)

  return (
    <video ref={videoElement} />
  )
}

however, I never got a single line printed, so to me it seems, as if there are no mutations there.但是,我从来没有打印过一行,所以在我看来,好像那里没有突变。

Did I maybe misunderstand something?我可能误会了什么吗? How can I react to the video-element being added to the document?我如何对添加到文档中的视频元素做出反应?

Ok, so I think I didn't provide enough information, but I found it out on my own:好的,所以我认为我没有提供足够的信息,但我自己发现了:

The MutationObserver doesn't work, because I told it to watch document , yet I'm actually inside of a shadowdom with this particular component! MutationObserver不起作用,因为我告诉它观看document ,但我实际上是在这个特定组件的影子中! So I suspect that mutations to the shadowdom won't be detected.所以我怀疑不会检测到暗影界的突变。

Also, because I'm inside of a shadowdom, document.contains(videoElem.current) will never be true.另外,因为我在 shadowdom 中,所以document.contains(videoElem.current)永远不会是真的。 So in this particular case I have no better choice, than to copy the code of qr-scanner into my project-tree and adapt as needed.因此,在这种特殊情况下,我没有更好的选择,只能将 qr-scanner 的代码复制到我的项目树中并根据需要进行调整。

On another note: useLayoutEffect is a react-hook, that is scheduled to run after DOM-mutations.另一方面: useLayoutEffect是一个 react-hook,它计划在 DOM 突变之后运行。 So that's what I would use if I had to start over with this idea.所以如果我必须从这个想法开始,这就是我会使用的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM