我在尝试将第三方产品之旅(对讲机)与react应用程序集成时遇到了一个问题。没有办法以编程方式结束我的found之旅。
基本上,我需要一个道具,每当某个非react DOM元素存在或不存在时,它都可以在react应用程序中更改。我需要能够在钩子或componentDidUpdate中辨别DOM中是否存在某个特定的非React元素。
我不确定该怎么做,因为很明显,当这个教程打开和关闭时,就react而言,状态或道具都没有变化。
有没有一种方法可以用像document.getElementById("Id-of-the-product-tour-overlay")这样的东西的结果作为道具来包装一个组件?有没有办法我可以用钩子看着它?
理想的情况是像这样
componentDidUpdate(){
if(elementExists){
//Do stuff that needs to happen while tour is on
}
if(!elementExists){
//do app stuff to end the tour
}
}
//OR
useEffect(()=>{
//do stuff conditional on element's existence
},[elementExists])发布于 2020-05-03 06:01:19
要做到这一点,最简单的方法是准备一个接收HTML元素的函数,并返回一个以参数形式接收回调的函数(返回其他函数的函数)。返回函数的结果是一个带有回调集的新MutationObserver。
const observeTarget = target => callback => {
const mutationObserver = new MutationObserver(callback);
mutationObserver.observe(target, { childList: true });
}在非react文件中,您可以向此函数提供一个HTML元素,该元素是您想要调查的第三方元素的容器。
然后导出该函数,您可以在react组件中使用它。
export const observeProductTourOverlay = observeTarget(containerOfProductTourOverlay);然后,在React组件中,您可以使用useEffect钩子并使用函数
const checkIFMyCompExists = () => !!document.querySelector("#my-component");
export const FromOutside = () => {
const [elementExists, setElementExist] = useState(checkIFMyCompExists());
const [indicator, setIndicator] = useState(3);
useEffect(() => {
observeProductTourOverlay((mutationRecord, observer) => {
const doesExist = checkIFMyCompExists();
setElementExist(doesExist);
// this will fire every time something inside container changes
// (i.e. a child is added or removed)
});
// garbage collector should take care of mutationObserver in a way there are no memory leaks, so no need to disconnect it on compoment unmouting.
}, []);
useEffect(() => {
setIndicator(elementExists);
//do stuff when elementExistance changes
}, [elementExists]);
return (
<div>
<div>{"my component has been added: " + indicator}</div>
</div>
);
};在这里找到工作演示:https://codesandbox.io/s/intelligent-morning-v1ndx
发布于 2020-05-03 05:59:20
可以使用while循环吗?
useEffect(()=>{
while (document.getElementById('theTour') !== null) {
// do stuff
}
// do cleanup
})https://stackoverflow.com/questions/61565239
复制相似问题