我想在index.html
内加载Google APIs client library,而onLoad='someMethod'
会在单独的javascript文件中调用方法。然后该方法将打印到控制台。
客户端库加载时没有任何问题,但是消息没有从控制台打印出来,我认为这是因为根本没有调用该方法。
这是我的index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
<div id="app"></div>
<script src="lib/vendors.js"></script>
<script src="build/bundle.js"></script>
<script src="https://apis.google.com/js/client.js?onload=handleGoogleClientLoad"></script>
</body>
以下是包含handleGoogleClientLoad
方法的javascript文件:
import React from 'react';
import ReactDOM from 'react-dom';
import {Button} from 'react-bootstrap';
class MyApp extends React.Component {
handleGoogleClientLoad() {
console.log('Success on load');
}
render() {
return (
<div>
<Button>Click Me</Button>
</div>
);
}
}
const app = document.getElementById('app');
ReactDOM.render(<MyApp />, app);
如果这是普通的javascript,方法将如下所示:
window.handleGoogleClientLoad = function() {
// Log to the console
};
es6中是否有与window
对象类似的内容。
答案 0 :(得分:10)
组件方法未附加到window
对象。 MyApp.handleGoogleClientLoad
不会与window.handleGoogleClientLoad
混淆,这是Google API脚本可能尝试调用的内容。
如果您希望Google API在您的组件上调用方法,那么您将遇到一些麻烦,因为无法保证在加载Google API脚本之前或之后安装您的组件。如果要保证在安装组件后必须注入脚本,并在componentDidMount
方法中注册该函数。您可以使用loadjs
componentDidMount() {
window.handleGoogleClientLoad = function() {
// log to console
}
loadjs('https://apis.google.com/js/client.js?onload=handleGoogleClientLoad')
}
答案 1 :(得分:0)
你的反应组件仍然可以使用window
对象..但问题是你定义你的函数很好,但你不是在任何地方调用它(是url中的jsonp语法)那个剧本?)。如果您希望在安装组件时执行该功能,则可以使用component lifecycle hooks,特别是componentDidMount
class MyApp extends React.Component {
handleGoogleClientLoad() {
console.log('Success on load');
}
componentDidMount(){
this.handleGoogleClientLoad();
}
render() {
return (
<div>
<Button>Click Me</Button>
</div>
);
}
}
如果您想保留已有的语法,那么您可以继续按照您的建议访问window
,但这绝对不是一种非常反应的方式
答案 2 :(得分:0)
一个老问题,但我在自己解决问题时就发现了。我正在使用React Helmet将东西放到<head>
中。我如何做到的如下。当使用defer
来加载gapi时,此处的关键是使用<script>
。这意味着它在文档被解析之前不会运行,这意味着我们的onload函数window.gapiInit
现在存在。
来自https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer:
此布尔属性设置为向浏览器指示脚本应在文档解析后但在触发DOMContentLoaded之前执行。
import React from "react"
import { Helmet } from "react-helmet"
const HeadHelmet: React.FC = () => {
if (typeof window != "undefined") { // needed if SSR
window.gapiInit = () => {
console.log({ gapiInit: true })
// set state, what ever you need
}
}
return (
<Helmet>
<script
src="https://apis.google.com/js/api.js?onload=gapiInit"
defer={true}
></script>
</Helmet>
)
}
export default HeadHelmet