web-dev-qa-db-ja.com

React、Redux、WebpackでGoogleAPIを実装する方法

GoogleカレンダーのイベントをReact Reduxアプリに取り込もうとしています。
googleapisとgoogle-auth-libraryを使用しようとしましたが、googleapisはサーバー側を実行するように構築されており、bundle.jsがクライアントから参照されているため、webpackがエラーをスローしています。だから私はこれらのエラーについていくつかのフォーラムを読みました、そしてそれらはすべて代わりに Googleのjsクライアントライブラリ を使用することを指しています。

これをJavaまたはphpアプリ(私は古い... 35;)で実装する方法を理解していますが、React Redux andこれを実装するための最良の方法を探しています。

私はactions.jsのカレンダーからイベントを取得しようとしています。 htmlヘッダーに<script src="https://apis.google.com/js/api.js"></script>を含めてから、actions.jsのgapi.load()を使用してみました。また、api.jsファイルを作成し、require( './ api')で参照してみました。また、Node.jsのcliコマンドを使用しようとしました クイックスタートガイド access_tokenを取得し、axiosを使用してGoogle APIを直接呼び出すだけですが、403を取得しています。 m適切なヘッダーを提供していないだけですが、とにかくそれはベストプラクティスではありません。

私の質問は基本的に、Redux標準に準拠しながら、actions.jsファイルからGoogleのjsクライアントライブラリを参照するにはどうすればよいですか?

8
pnkflydgr

いくつかの非常に良い正解にもかかわらず、私は自分の質問に答えるつもりです。 @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/[email protected]/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のものに取り組むつもりです:/

1
pnkflydgr

ReactアプリでNPMモジュールが見つからなかったときに、外部ライブラリとモジュールをロードするために使用したこのライブラリを試してみてください。

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
});
3
MattYao

HTMLヘッダーに公式のGoogleクライアントAPIを含めることで、正しい方向に進んでいます。それは理想的とは言えません。Googleが(ブラウザの)クライアントAPIをnpmモジュールとしてimportできるように提供してくれればいいのですが。しかし、そうではないので(私が見る限り)、あなたがしていることは問題ないと思います。

次に、「React/Reduxに適した方法で使用するにはどうすればよいですか?」という質問があります。 Reduxはアプリケーションの状態を管理するためのメカニズムです。 Google APIはアプリケーションの一部ではありません(ただし、Google APIを使用すると、アプリケーションの状態が通知される場合があります)。

GoogleAPIにアクセスできることを確認するのは簡単です。コンポーネントの1つの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に適した方法でそれを利用する方法はありますか?

GAPI呼び出しを行うときは、おそらく何らかの方法でアプリケーションの状態を変更する必要があります(そうでない場合は、なぜそれを行うのでしょうか)。たとえば、認証フローを呼び出し、GAPIが成功を返すと、アプリケーションの状態はloggedIn: trueになります。または同様のもの(おそらく他の多くの状態変化を伴う)。 GAPI呼び出しを行う場所はあなた次第です。コンポーネントのロード時に実行する場合は、componentDidMountで実行する必要があります。また、通常、ボタンのクリックなどのユーザーアクションに応答してGAPI呼び出しを行う場合もあります。

したがって、一般的なフローは次のようになります。

// either in componentDidMount, or a control handler, usually:
someGapiCall()
  .then(result => {
    this.props.onGapiThing(result.whatever)
  })

ここで、this.props.onGapiThingは、アプリケーションの状態を変更する適切なアクションをディスパッチする関数です。

この概要がお役に立てば幸いです...より具体的な質問を気軽にフォローアップしてください。

3
Ethan Brown

Webpackバンドルをロードする前にインデックスファイルにすべてのグーグルのものをロードします( オプション1 )。次に、 redux sagas を使用してGoogleAPIを呼び出します。 Webpackバンドルの前にGoogleコードをロードすると、SagaからAPIを呼び出すときにすべての準備が整います。

0
pizza-r0b