如何用 React、Redux 和 Webpack 实现 Google API
How to implement Google API with React, Redux and Webpack
我正在尝试将 google 日历事件添加到我的 React Redux 应用程序中。
我试过使用 googleapis 和 google-auth-library 但是 webpack 抛出错误,因为 googleapis 是为 运行 服务器端构建的,并且bundle.js 从客户端引用。
所以我已经阅读了一些关于这些错误的论坛,它们都指向使用 Google's js client library 来代替。
我知道如何在 java 或 php 应用程序中实现它(我老了... 35 ;)但我是 React Redux 的新手,我正在寻找实现这一目标的最佳方式。
我正在尝试从 actions.js 中的日历中获取活动。我尝试在 html header 中包含 <script src="https://apis.google.com/js/api.js"></script>
,然后使用 actions.js 中的 gapi.load()。我还尝试创建一个 api.js 文件并使用 require('./api') 引用它。我还尝试使用 Node.js Quickstart guide 中的 cli 命令来获取 access_token 然后使用 axios 直接调用 Google API 但我收到 403。我想我只是没有提供正确的 headers 但无论如何这都不是最佳做法。
我的问题基本上是如何在遵守 Redux 标准的同时从我的 actions.js 文件中引用 Google 的 js 客户端库?
当我找不到 NPM 模块时,你能试试这个库吗?我用它在我的 React 应用程序中加载外部库和模块:
https://github.com/ded/script.js/
所以你的代码将是这样的:
import $script from 'scriptjs';
$script('https://apis.google.com/js/api.js', function () {
//Put your google api functions here as callback
});
我会在加载我的 webpack 包之前加载索引文件中的所有 google 内容(Option 1) . Then I would use redux sagas 调用 google apis。加载 google webpack bundle 之前的代码将确保当你从 saga
中调用 api 时一切准备就绪
将官方 Google 客户端 API 包含在 HTML header 中,您走在了正确的轨道上。它不太理想——如果 Google 提供(浏览器)客户端 API 作为一个 npm 模块,你可以 import
。但是他们没有(我看到了),所以我认为你做的很好。
然后是 "how do I use it in a way that's React/Redux friendly?" 的问题,Redux 是一种管理应用程序状态的机制。 Google API 不是您的应用程序的一部分(尽管您对它所做的操作可能会告知您的应用程序状态)。
验证您是否有权访问 Google API 很容易:您只需从组件之一的 componentDidMount
方法进行调用,然后执行控制台日志:
class MyComp extends React.Component {
componentDidMount() {
// this is taken directly from Google documentation:
// https://developers.google.com/api-client-library/javascript/start/start-js
function start() {
// 2. Initialize the JavaScript client library.
gapi.client.init({
'apiKey': 'YOUR_API_KEY',
// clientId and scope are optional if auth is not required.
'clientId': 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
'scope': 'profile',
}).then(function() {
// 3. Initialize and make the API request.
return gapi.client.request({
'path': 'https://people.googleapis.com/v1/people/me',
})
}).then(function(response) {
console.log(response.result);
}, function(reason) {
console.log('Error: ' + reason.result.error.message);
});
};
// 1. Load the JavaScript client library.
gapi.load('client', start);
},
}
如果您在控制台上没有看到您期望的内容,可能是 gapi
没有按您期望的方式加载。如果发生这种情况,您可以提出更具体的问题!
如果您确实得到响应,您现在知道如何调用 GAPI...但是如何以 Redux-friendly 方式使用它?
当您进行 GAPI 调用时,您可能希望以某种方式修改应用程序的状态(否则您为什么要这样做?)例如,您可能会调用身份验证流程,以及何时GAPI returns 成功,您的应用程序状态现在有 loggedIn: true
或类似的(可能有很多其他状态更改)。您在哪里进行 GAPI 调用由您决定。如果你想在组件加载时执行它,你应该在 componentDidMount
中执行。您也可能经常发出 GAPI 调用以响应用户操作,例如单击按钮。
所以典型的流程是这样的:
// either in componentDidMount, or a control handler, usually:
someGapiCall()
.then(result => {
this.props.onGapiThing(result.whatever)
})
其中 this.props.onGapiThing
是调度适当操作的函数,该操作会修改您的应用程序状态。
希望这篇概述对您有所帮助...请随时提出更具体的问题。
尽管有一些非常正确的答案,我还是要回答我自己的问题。
@MattYao 回答了我的实际问题,即如何在我的 actions.js 文件中获取可供参考的 js 脚本。
@Ethan Brown 给出了一个非常详细的答案,显示了一些极好的流量可能性。
@realseanp 更改了范围但有效答案。
我尝试了以上所有方法,它们都有效。
所以我不确定我做错了什么,但我终于能够通过将 <script src="https://apis.google.com/js/api.js"></script>
添加到我的索引头来从 actions.js 访问 gapi 对象。
我正在使用哈巴狗所以它看起来像这样:
doctype
html
head
title MyTitle
link(rel='stylesheet' href='/static/css/main.css')
link(rel='stylesheet' href='/static/css/react-big-calendar.css')
script(src='https://apis.google.com/js/api.js' type='text/javascript')
body
div(id='app')
script(src='/static/bundle.js' type='text/javascript')
这是我的组件文件:
import React from 'react'
import BigCalendar from 'react-big-calendar';
import moment from 'moment';
import { connect } from 'react-redux'
import { fetchEvents } from '../actions/actions'
BigCalendar.momentLocalizer(moment);
@connect((store) => {
return {
events: store.events.events
}
})
export default class Calendar extends React.Component
{
componentWillMount()
{
this.props.dispatch(fetchEvents())
}
render()
{
return (
<div>
<BigCalendar
events={this.props.events}
startAccessor='startDate'
endAccessor='endDate'
style={{height: 800}}
/>
</div>
)
}
}
然后我就可以在我的 actions.js 文件中使用它了
export function fetchEvents()
{
return (dispatch) =>
{
function start()
{
// 2. Initialize the JavaScript client library.
gapi.client.init({
'apiKey': API_KEY,
// clientId and scope are optional if auth is not required.
'clientId': CLIENT_ID,
'scope': 'profile',
}).then(function() {
// 3. Initialize and make the API request.
return gapi.client.request({
'path': 'https://www.googleapis.com/calendar/v3/calendars/MY_EMAIL@gmail.com/events?timeMax=2017-06-03T23:00:00Z&timeMin=2017-04-30T00:00:00Z',
})
}).then( (response) => {
let events = response.result.items
dispatch({
type: 'FETCH_EVENTS_FULFILLED',
payload: events
})
}, function(reason) {
console.log(reason);
});
};
// 1. Load the JavaScript client library.
gapi.load('client', start)
}}
我必须让我的日历 public 才能以这种方式访问它。所以现在我要处理 oauth2 的事情了:/
试试这个包。
看起来它已更新。
https://github.com/QuodAI/tutorial-react-google-api-login
我正在尝试将 google 日历事件添加到我的 React Redux 应用程序中。
我试过使用 googleapis 和 google-auth-library 但是 webpack 抛出错误,因为 googleapis 是为 运行 服务器端构建的,并且bundle.js 从客户端引用。
所以我已经阅读了一些关于这些错误的论坛,它们都指向使用 Google's js client library 来代替。
我知道如何在 java 或 php 应用程序中实现它(我老了... 35 ;)但我是 React Redux 的新手,我正在寻找实现这一目标的最佳方式。
我正在尝试从 actions.js 中的日历中获取活动。我尝试在 html header 中包含 <script src="https://apis.google.com/js/api.js"></script>
,然后使用 actions.js 中的 gapi.load()。我还尝试创建一个 api.js 文件并使用 require('./api') 引用它。我还尝试使用 Node.js Quickstart guide 中的 cli 命令来获取 access_token 然后使用 axios 直接调用 Google API 但我收到 403。我想我只是没有提供正确的 headers 但无论如何这都不是最佳做法。
我的问题基本上是如何在遵守 Redux 标准的同时从我的 actions.js 文件中引用 Google 的 js 客户端库?
当我找不到 NPM 模块时,你能试试这个库吗?我用它在我的 React 应用程序中加载外部库和模块:
https://github.com/ded/script.js/
所以你的代码将是这样的:
import $script from 'scriptjs';
$script('https://apis.google.com/js/api.js', function () {
//Put your google api functions here as callback
});
我会在加载我的 webpack 包之前加载索引文件中的所有 google 内容(Option 1) . Then I would use redux sagas 调用 google apis。加载 google webpack bundle 之前的代码将确保当你从 saga
中调用 api 时一切准备就绪将官方 Google 客户端 API 包含在 HTML header 中,您走在了正确的轨道上。它不太理想——如果 Google 提供(浏览器)客户端 API 作为一个 npm 模块,你可以 import
。但是他们没有(我看到了),所以我认为你做的很好。
然后是 "how do I use it in a way that's React/Redux friendly?" 的问题,Redux 是一种管理应用程序状态的机制。 Google API 不是您的应用程序的一部分(尽管您对它所做的操作可能会告知您的应用程序状态)。
验证您是否有权访问 Google API 很容易:您只需从组件之一的 componentDidMount
方法进行调用,然后执行控制台日志:
class MyComp extends React.Component {
componentDidMount() {
// this is taken directly from Google documentation:
// https://developers.google.com/api-client-library/javascript/start/start-js
function start() {
// 2. Initialize the JavaScript client library.
gapi.client.init({
'apiKey': 'YOUR_API_KEY',
// clientId and scope are optional if auth is not required.
'clientId': 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
'scope': 'profile',
}).then(function() {
// 3. Initialize and make the API request.
return gapi.client.request({
'path': 'https://people.googleapis.com/v1/people/me',
})
}).then(function(response) {
console.log(response.result);
}, function(reason) {
console.log('Error: ' + reason.result.error.message);
});
};
// 1. Load the JavaScript client library.
gapi.load('client', start);
},
}
如果您在控制台上没有看到您期望的内容,可能是 gapi
没有按您期望的方式加载。如果发生这种情况,您可以提出更具体的问题!
如果您确实得到响应,您现在知道如何调用 GAPI...但是如何以 Redux-friendly 方式使用它?
当您进行 GAPI 调用时,您可能希望以某种方式修改应用程序的状态(否则您为什么要这样做?)例如,您可能会调用身份验证流程,以及何时GAPI returns 成功,您的应用程序状态现在有 loggedIn: true
或类似的(可能有很多其他状态更改)。您在哪里进行 GAPI 调用由您决定。如果你想在组件加载时执行它,你应该在 componentDidMount
中执行。您也可能经常发出 GAPI 调用以响应用户操作,例如单击按钮。
所以典型的流程是这样的:
// either in componentDidMount, or a control handler, usually:
someGapiCall()
.then(result => {
this.props.onGapiThing(result.whatever)
})
其中 this.props.onGapiThing
是调度适当操作的函数,该操作会修改您的应用程序状态。
希望这篇概述对您有所帮助...请随时提出更具体的问题。
尽管有一些非常正确的答案,我还是要回答我自己的问题。 @MattYao 回答了我的实际问题,即如何在我的 actions.js 文件中获取可供参考的 js 脚本。 @Ethan Brown 给出了一个非常详细的答案,显示了一些极好的流量可能性。 @realseanp 更改了范围但有效答案。
我尝试了以上所有方法,它们都有效。
所以我不确定我做错了什么,但我终于能够通过将 <script src="https://apis.google.com/js/api.js"></script>
添加到我的索引头来从 actions.js 访问 gapi 对象。
我正在使用哈巴狗所以它看起来像这样:
doctype
html
head
title MyTitle
link(rel='stylesheet' href='/static/css/main.css')
link(rel='stylesheet' href='/static/css/react-big-calendar.css')
script(src='https://apis.google.com/js/api.js' type='text/javascript')
body
div(id='app')
script(src='/static/bundle.js' type='text/javascript')
这是我的组件文件:
import React from 'react'
import BigCalendar from 'react-big-calendar';
import moment from 'moment';
import { connect } from 'react-redux'
import { fetchEvents } from '../actions/actions'
BigCalendar.momentLocalizer(moment);
@connect((store) => {
return {
events: store.events.events
}
})
export default class Calendar extends React.Component
{
componentWillMount()
{
this.props.dispatch(fetchEvents())
}
render()
{
return (
<div>
<BigCalendar
events={this.props.events}
startAccessor='startDate'
endAccessor='endDate'
style={{height: 800}}
/>
</div>
)
}
}
然后我就可以在我的 actions.js 文件中使用它了
export function fetchEvents()
{
return (dispatch) =>
{
function start()
{
// 2. Initialize the JavaScript client library.
gapi.client.init({
'apiKey': API_KEY,
// clientId and scope are optional if auth is not required.
'clientId': CLIENT_ID,
'scope': 'profile',
}).then(function() {
// 3. Initialize and make the API request.
return gapi.client.request({
'path': 'https://www.googleapis.com/calendar/v3/calendars/MY_EMAIL@gmail.com/events?timeMax=2017-06-03T23:00:00Z&timeMin=2017-04-30T00:00:00Z',
})
}).then( (response) => {
let events = response.result.items
dispatch({
type: 'FETCH_EVENTS_FULFILLED',
payload: events
})
}, function(reason) {
console.log(reason);
});
};
// 1. Load the JavaScript client library.
gapi.load('client', start)
}}
我必须让我的日历 public 才能以这种方式访问它。所以现在我要处理 oauth2 的事情了:/
试试这个包。 看起来它已更新。 https://github.com/QuodAI/tutorial-react-google-api-login