Javascript 检测生命周期方法或挂钩中的页面上是否存在非react元素
我在尝试将第三方产品巡更(Intercom)与react应用程序集成时遇到了一个问题。没有办法以编程方式结束我的旅行 基本上,我需要一个道具,无论是否存在某个非react DOM元素,它都可以在react应用程序中更改。我需要能够在hook或Javascript 检测生命周期方法或挂钩中的页面上是否存在非react元素,javascript,reactjs,intercom,Javascript,Reactjs,Intercom,我在尝试将第三方产品巡更(Intercom)与react应用程序集成时遇到了一个问题。没有办法以编程方式结束我的旅行 基本上,我需要一个道具,无论是否存在某个非react DOM元素,它都可以在react应用程序中更改。我需要能够在hook或componentdiddupdate中判断DOM中是否存在某个非React元素 我不知道该怎么办,因为很明显,当这个巡演开始和结束时,就react而言,状态和道具都没有变化 有没有一种方法可以将类似于document.getElementById(“产品巡
componentdiddupdate
中判断DOM中是否存在某个非React元素
我不知道该怎么办,因为很明显,当这个巡演开始和结束时,就react而言,状态和道具都没有变化
有没有一种方法可以将类似于document.getElementById(“产品巡更覆盖的Id”)
的结果包装成一个组件作为道具?有没有办法让我用钩子来看着它
理想情况下
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])
你能用一会儿吗
useEffect(()=>{
while (document.getElementById('theTour') !== null) {
// do stuff
}
// do cleanup
})
这样做的简单方法是准备一个函数,该函数接收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>
);
};
const checkIFMyCompExists=()=>!!document.querySelector(“我的组件”);
从外部导出常量=()=>{
const[elementExists,setelementexists]=useState(checkIFMyCompExists());
const[indicator,setIndicator]=使用状态(3);
useffect(()=>{
observeProductTourOverlay((变异记录,观察者)=>{
const doesExist=checkIFMyCompExists();
setElementExist(性别歧视);
//每当容器内的内容发生变化时,该命令就会触发
//(即添加或删除儿童)
});
//垃圾收集器应该以一种不存在内存泄漏的方式来处理mutationObserver,因此无需在组件卸载时断开它的连接。
}, []);
useffect(()=>{
setIndicator(elementExists);
//当elementExistance发生变化时做一些事情
},[elementExists]);
返回(
{“我的组件已添加:“+指示器}”
);
};
在此处找到工作演示:Ok。看起来它对子列表中的更改的响应很好。但是它在几秒钟后抛出这个错误`TypeError:cannotreadproperty'getElementByID'为undefined`对于这一行
constdoesexist=!!mutationRecord.target.getElementByID(“产品巡更覆盖的Id”)
我正在使用document.body
作为observeTarget
参数,因为它是巡更的唯一父项。解决方案适用于不是
的父项和子项或body
的直接子项的父项和子项。第三方产品巡更是document.body
的直接子产品。还尝试了document.body | | document.documentElement
,这导致未观察到任何更改。我得到初始的元素exists:false
但没有后续的更改。try const doesExist=!!document.getElementByID(“产品巡更覆盖的Id”);稍后我将实现整个解决方案,并将粘贴到此处