我正在尝试在反应js应用中实现谷歌日历api的this vanilla js示例。 vanilla 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')
);
截至目前我遇到此错误:
未捕获的TypeError:无法读取属性&#39; isSignedIn&#39;为null
请指导我进一步......
答案 0 :(得分:3)
最后添加我的解决方案,以帮助未来的人员:)
要获取事件列表,不需要授权。因此,从Google的快速启动示例中删除了不必要的代码。
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。
答案 1 :(得分:1)
您已将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')
);
答案 2 :(得分:0)
我正在使用HOC加载google 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);
然后,您可以像调用日历一样调用gogle API,例如:
const event = this.buildEventoGoogle(values);
const request = window.gapi.client.calendar.events.insert({
calendarId: "primary",
resource: event
});