我想实现在反应JS应用谷歌日历API的this香草js的例子。香草JS例如在我的本地机器上工作得很好。但我实现相同的反应时,得到很多麻烦。请在下面检查我的代码:
class App extends React.Component{
constructor(props) {
super(props);
var CLIENT_ID = '992549188018-3prg54pp18je3e3qhgcttgl11491c4dm.apps.googleusercontent.com';
var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"];
var SCOPES = "https://www.googleapis.com/auth/calendar";
this.state = {
showAuthButton: false,
showSignOutButton: false
};
this.initClient = this.initClient.bind(this);
this.updateSigninStatus = this.updateSigninStatus.bind(this);
}
handleAuthClick(){
gapi.auth2.getAuthInstance().signIn();
}
handleSignoutClick(){
gapi.auth2.getAuthInstance().signOut();
}
handleClientLoad() {
gapi.load('client:auth2', this.initClient);
}
initClient(DISCOVERY_DOCS, CLIENT_ID, SCOPES) {
gapi.client.init({
discoveryDocs: DISCOVERY_DOCS,
clientId: CLIENT_ID,
scope: SCOPES
}).then(function () {
console.log(window.gapi);
// Listen for sign-in state changes.
window.gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
});
}
updateSigninStatus(isSignedIn) {
if (isSignedIn) {
this.setState({
showAuthButton: false,
showSignOutButton: true
})
//listUpcomingEvents();
//insertNewEvent();
} else {
this.setState({
showAuthButton: true,
showSignOutButton: false
})
}
}
componentDidMount(){
this.handleClientLoad();
}
render(){
let authButton = <button id="authorize-button" onClick={this.handleAuthClick.bind(this)}>Authorize</button>
let signOutButton = <button id="signout-button" onClick={this.handleSignoutClick.bind(this)}>Sign Out</button>
return(
<div className="container">
{this.state.showAuthButton ? authButton : null}
{this.state.showSignOutButton ? signOutButton : null}
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
正在此错误截至目前:
遗漏的类型错误:无法读取空的特性“isSignedIn”
请指导我进一步移动...
最后加入我的解决方案,致力于帮助未来的后起之秀:)
要获得事件列表,不需要授权。所以移除了谷歌的快速入门例子中不必要的代码。
componentDidMount = () => {
this.getEvents();
}
getEvents(){
let that = this;
function start() {
gapi.client.init({
'apiKey': GOOGLE_API_KEY
}).then(function() {
return gapi.client.request({
'path': `https://www.googleapis.com/calendar/v3/calendars/${CALENDAR_ID}/events`,
})
}).then( (response) => {
let events = response.result.items
that.setState({
events
}, ()=>{
console.log(that.state.events);
})
}, function(reason) {
console.log(reason);
});
}
gapi.load('client', start)
}
你可以找到完整的代码和功能演示here。
你感动GAPI配置变量在组件的外面,但迟迟无法访问没有从initClient
参数删除它们。下面是正确的代码:
var CLIENT_ID = '992549188018-3prg54pp18je3e3qhgcttgl11491c4dm.apps.googleusercontent.com';
var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"];
var SCOPES = "https://www.googleapis.com/auth/calendar";
class App extends React.Component{
constructor(props) {
super(props);
this.state = {
showAuthButton: false,
showSignOutButton: false
};
this.initClient = this.initClient.bind(this);
this.updateSigninStatus = this.updateSigninStatus.bind(this);
}
handleAuthClick(){
gapi.auth2.getAuthInstance().signIn();
}
handleSignoutClick(){
gapi.auth2.getAuthInstance().signOut();
}
handleClientLoad() {
gapi.load('client:auth2', this.initClient);
}
initClient(/****here you've had parameters that made config vars unaccessible*****/) {
gapi.client.init({
discoveryDocs: DISCOVERY_DOCS,
clientId: CLIENT_ID,
scope: SCOPES
}).then(function () {
console.log(window.gapi);
// Listen for sign-in state changes.
// ************* to access instance method you have to use `this.updateSigninStatus`
window.gapi.auth2.getAuthInstance().isSignedIn.listen(this.updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
// **************this code is unnecessary and causes errors*****
// authorizeButton.onclick = handleAuthClick;
// signoutButton.onclick = handleSignoutClick;
});
}
updateSigninStatus(isSignedIn) {
if (isSignedIn) {
this.setState({
showAuthButton: false,
showSignOutButton: true
})
//listUpcomingEvents();
//insertNewEvent();
} else {
this.setState({
showAuthButton: true,
showSignOutButton: false
})
}
}
componentDidMount(){
this.handleClientLoad();
}
render(){
let authButton = <button id="authorize-button" onClick={this.handleAuthClick.bind(this)}>Authorize</button>
let signOutButton = <button id="signout-button" onClick={this.handleSignoutClick.bind(this)}>Sign Out</button>
return(
<div className="container">
{this.state.showAuthButton ? authButton : null}
{this.state.showSignOutButton ? signOutButton : null}
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
我使用的是HOC加载谷歌API:
import React from "react";
import { API_KEY } from "./constants";
import LoadingIndicator from "./common/LoadingIndicator";
export default function withGoogleApps(WrappedComponent) {
class ComponentWithGoogleAPI extends React.Component {
state = { gapiReady: false };
componentDidMount() {
this.loadGoogleAPI();
}
loadGoogleAPI() {
const script = document.createElement("script");
script.src = "https://apis.google.com/js/client.js";
script.onload = () => {
window.gapi.load("client", () => {
window.gapi.client.setApiKey(API_KEY);
window.gapi.client.load("calendar", "v3", () => {
this.setState({ gapiReady: true });
});
});
};
document.body.appendChild(script);
}
render() {
const { gapiReady } = this.state;
if (gapiReady) return <WrappedComponent />;
return <LoadingIndicator />;
}
}
return ComponentWithGoogleAPI;
}
在你这样称呼它:
import withGoogleApps from "./withGoogleApps";
const AppConGoogle = withGoogleApps(App);
然后,你可以调用谷歌API,如日历,例如:
const event = this.buildEventoGoogle(values);
const request = window.gapi.client.calendar.events.insert({
calendarId: "primary",
resource: event
});