如何使用React,Redux和Webpack实现Google API

时间:2017-05-01 03:19:57

标签: node.js reactjs webpack redux react-redux

我试图将谷歌日历活动纳入我的React Redux应用程序 我尝试过使用googleapis和google-auth-library但是webpack会抛出错误,因为googleapis是为运行服务器端而构建的,而bundle.js是从客户端引用的。 所以我已经阅读了几个关于这些错误的论坛,他们都指向使用Google's js client library

我理解如何在java或php应用程序中实现它(我已经35岁了);但我是React Redux的新手,我正在寻找最好的方法实现这一点。

我试图在我的actions.js中从我的日历中获取事件。我尝试在我的html标题中包含<script src="https://apis.google.com/js/api.js"></script>,然后使用actions.js中的gapi.load()。我还尝试创建一个api.js文件并使用require引用它(&#39; ./ api&#39;)。我还尝试使用Node.js Quickstart guide中的cli命令来获取access_token,然后直接使用axios来调用Google API,但我得到了403.我在想我&# 39;我只是没有提供合适的标题,但无论如何这都不是最好的做法。

我的问题基本上是如何在遵守Redux标准的情况下从我的actions.js文件中引用Google的js客户端库?

4 个答案:

答案 0 :(得分:3)

当我找不到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
});

答案 1 :(得分:3)

通过在HTML标头中加入官方Google客户端API,您已走上正轨。它不太理想 - 如果谷歌提供(浏览器)客户端API作为你可以import的npm模块,那就太好了。但他们没有(我看到),所以我认为你做的很好。

那么问题是&#34;我如何以一种React / Redux友好的方式使用它?&#34; 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无法按预期加载loggedIn: true。如果发生这种情况,您可以提出更具体的问题!

如果您收到回复,您现在知道如何调用GAPI ......但是如何以Redux友好的方式使用它?

当您进行GAPI调用时,您可能希望以某种方式修改应用程序的状态(否则您为什么要这样做?)例如,您可能会调用auth流程,并且当GAPI返回成功时,您的应用程序状态现在具有componentDidMount或类似(可能还有许多其他状态更改)。您在哪里进行GAPI通话取决于您。如果要在加载组件时执行此操作,则应在// either in componentDidMount, or a control handler, usually: someGapiCall() .then(result => { this.props.onGapiThing(result.whatever) }) 中执行此操作。您也可能通常在响应用户操作时进行GAPI调用,例如单击按钮。

所以典型的流程是这样的:

this.props.onGapiThing

其中// App.js import IntroductionPage from './IntroductionPage' 是一个调度适当操作的函数,它会修改您的应用程序状态。

我希望此概述有助于...随时提出更具体的问题。

答案 2 :(得分:1)

尽管有一些非常好的正确答案,我还是要回答我自己的问题。 @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)
}}

我必须公开我的日历才能以这种方式访问​​它。所以现在我要开始研究oauth2的东西:/

答案 3 :(得分:0)

在加载我的webpack包(Option 1)之前,我会在我的索引文件中加载所有google内容。然后我会使用redux sagas来调用google apis。在你的webpack包之前加载谷歌代码将确保你从传奇中调用api时已经准备好了所有内容