Reactjs 如何清理单页应用程序上的嵌入式youtube订阅按钮
我在正在构建的单页应用程序中嵌入了youtube订阅按钮。它可以正常加载,但当我导航到其他路由时,该路由的渲染会显示以下错误消息:Reactjs 如何清理单页应用程序上的嵌入式youtube订阅按钮,reactjs,react-router,youtube-api,youtube-data-api,google-api-js-client,Reactjs,React Router,Youtube Api,Youtube Data Api,Google Api Js Client,我在正在构建的单页应用程序中嵌入了youtube订阅按钮。它可以正常加载,但当我导航到其他路由时,该路由的渲染会显示以下错误消息: cb=gapi.loaded_0:150 Uncaught DOMException: Blocked a frame with origin "https://www.youtube.com" from accessing a cross-origin frame. at Object.nz [as kq] (https://apis.google.co
cb=gapi.loaded_0:150
Uncaught DOMException: Blocked a frame with origin "https://www.youtube.com" from accessing a cross-origin frame.
at Object.nz [as kq] (https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.xh-S9KbEGSE.O/m=gapi_iframes,gapi_iframes_style_common/rt=j/sv=1/d=1/ed=1/am=wQc/rs=AGLTcCNaUSRWzhd71dAsiMVOstVE3KcJZw/cb=gapi.loaded_0:150:257)
at jz.send (https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.xh-S9KbEGSE.O/m=gapi_iframes,gapi_iframes_style_common/rt=j/sv=1/d=1/ed=1/am=wQc/rs=AGLTcCNaUSRWzhd71dAsiMVOstVE3KcJZw/cb=gapi.loaded_0:148:261)
at Fz (https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.xh-S9KbEGSE.O/m=gapi_iframes,gapi_iframes_style_common/rt=j/sv=1/d=1/ed=1/am=wQc/rs=AGLTcCNaUSRWzhd71dAsiMVOstVE3KcJZw/cb=gapi.loaded_0:152:349)
at https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.xh-S9KbEGSE.O/m=gapi_iframes,gapi_iframes_style_common/rt=j/sv=1/d=1/ed=1/am=wQc/rs=AGLTcCNaUSRWzhd71dAsiMVOstVE3KcJZw/cb=gapi.loaded_0:152:259
甚至当我去一个没有“订阅”按钮的路线时,这种情况也会发生(只要我以前在一个有按钮的路线上)。我主要关心的不是错误的原因,而是页面上不再存在的subscribe按钮导致了错误。更糟糕的是,当我在整个应用程序中导航时,在我访问的每一条带有“订阅”按钮的路线之后,似乎都会注册一个额外的侦听器(或任何导致此情况的原因)。然后,该消息在每个路由渲染上打印多次,对于自上次刷新以来安装的每个按钮打印一次。为了便于参考,我附上了我的组件:
import React, { useEffect, useRef } from 'react';
import { observer } from 'mobx-react-lite';
import useScript from 'react-script-hook';
import './YoutubeSubscriberButton.scss';
interface Props {
youtubeChannel: string
}
type gapiType = typeof gapi;
interface gapiYt extends gapiType {
ytsubscribe: {
render: (container: HTMLElement, parameters: {'channel': string, 'layout': string}) => any
}
}
const YoutubeSubscriberButton: React.FC<Props> = observer(({ youtubeChannel }: Props): JSX.Element|null => {
const [gapiLoading, gapiError] = useScript({ src: 'https://apis.google.com/js/platform.js'});
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const container = containerRef.current;
if (!youtubeChannel || !container) {
return;
}
while (container.firstChild) {
container.removeChild(container.firstChild);
}
if (gapiLoading || gapiError) {
return;
}
(gapi as gapiYt).ytsubscribe.render(container, {
'channel': youtubeChannel,
'layout': 'full'
});
return (() =>{
while (container && container.firstChild) {
container.removeChild(container.firstChild);
}
});
}, [youtubeChannel, gapiLoading, gapiError]);
return (
<div className="youtube-subscriber-button-component">
<div className="youtube-subscriber-button-container" ref={containerRef}/>
</div>
);
});
export default YoutubeSubscriberButton;
import React,{useffect,useRef}来自“React”;
从'mobx react lite'导入{observer};
从“反应脚本挂钩”导入useScript;
导入“/YoutubeSubscriberButton.scss”;
界面道具{
youtubeChannel:字符串
}
类型gapiType=gapi的类型;
接口gapiYt扩展了gapiType{
订阅:{
render:(容器:HTMLElement,参数:{'channel':string,'layout':string})=>any
}
}
const YoutubeSubscriberButton:React.FC=observer({youtubeChannel}:Props):JSX.Element|null=>{
const[gapiloding,gapiError]=useScript({src:'https://apis.google.com/js/platform.js'});
const containerRef=useRef(null);
useffect(()=>{
const container=containerRef.current;
如果(!youtubeChannel | |!容器){
返回;
}
while(container.firstChild){
container.removeChild(container.firstChild);
}
if(gapiloding | | gapiError){
返回;
}
(gapi作为gapiYt.ytsubscribe.render(容器{
“频道”:youtubeChannel,
“布局”:“完整”
});
返回(()=>{
while(container&&container.firstChild){
container.removeChild(container.firstChild);
}
});
},[youtubeChannel,gapiLoading,gapiError];
返回(
);
});
导出默认YoutubeSubscriberButton;
有没有一个好方法可以让我清理gapi对象、youtube订阅按钮iframe或其他导致此问题的原因?我基于实现youtube订阅按钮的解决方案制作了CodeSandbox。我用反应路线检查了一下,没有问题
您可以在应用程序功能中替换数据通道ID
,以查看其工作情况
您可以找到您的唯一Youtube频道ID:
class=“g-ytsubscribe”
数据通道ID=“”
数据布局=“完整”
数据主题=“黑暗”
数据计数=“隐藏”
class="g-ytsubscribe"
data-channelid="<YOUR CHANNEL ID HERE>"
data-layout="full"
data-theme="dark"
data-count="hidden"