2017-04-25 9 views
0

私は基本的にReactコンポーネントクラスのcomponentWillMount()関数内からこれを実行しようとしています。完全を期すためにここに貼り付けサードパーティのJSファイルからのReactJS状態の設定onload

const script = document.createElement("script"); 

    script.src = "https://apis.google.com/js/client.js"; 
    script.async = true; 
    script.onload = function() { 
     gapi.client.setApiKey(API_KEY); 
     gapi.client.load('youtube', 'v3'); 
     this.setState({ gapiReady: true }); 
     //^Doesn't work because `this` refers to the script rather than the component itself. 
    }; 

    document.body.appendChild(script); 

全体コンポーネント:

import React, { Component } from 'react'; 
import VideoPlayer from '../../components/VideoPlayer/VideoPlayer'; 
import VideoInfo from '../../components/VideoInfo/VideoInfo'; 
import SearchBox from '../../components/SearchBox/SearchBox'; 
import './App.css'; 

class App extends Component { 
    constructor(props, context) { 
    super(props, context); 
    this.state = {}; 
    }; 

    componentWillMount() { 
    const script = document.createElement("script"); 

    script.src = "https://apis.google.com/js/client.js"; 
    script.async = true; 
    script.onload = function() { 
     gapi.client.setApiKey(API_KEY); 
     gapi.client.load('youtube', 'v3'); 
     this.setState({ gapiReady: true }); // Doesn't work because `this` refers to the script rather than the component 
    }; 

    document.body.appendChild(script); 
    }; 

    render() { 
    if (this.state.gapiReady) { 
     return (
     <div className="wrap"> 
      <div className="sidebar"> 
      <SearchBox /> 
      <VideoInfo videoId="vkRDOcma9Qk" /> 
      </div> 
      <div className="content"> 
      <VideoPlayer /> 
      </div> 
     </div> 
    ); 
    } else { 
     return (
     <div>Loading...</div> 
    ) 
    } 
    }; 
} 

export default App; 

この上の理由それ以外のコード私の目標は、スクリプトが完全にロードされたときに、レンダリング()関数でVideoInfoとのVideoPlayerコンポーネントをレンダリングするだけにありますコンポーネントはロードされたスクリプトに依存しているので失敗します。

私はこれについて間違った方法をしていますか?

答えて

1

まず、オブジェクトにアクセスできない場合でもコードを実行できるように、これはcomponentDidMountのようにする必要があります。これはサーバー側のレンダリングをしていない場合は大したことではありませんが、Reactの一般的なパターンです。

thisで問題を解決するには、矢印機能を使用してscript.onloadを定義します。矢印の機能で定義された関数は、新しいコンテキストを作成していないので、this関数がで定義されている範囲と同じまま

TLDRは、これであなたのcomponentWillMountメソッドを置き換えます。

componentDidMount() { 
    const script = document.createElement("script") 

    script.src = "https://apis.google.com/js/client.js" 
    script.async = true 

    script.onload =() => { 
    gapi.client.setApiKey(API_KEY) 
    gapi.client.load('youtube', 'v3') 
    this.setState({ gapiReady: true }) 
    } 

    document.body.appendChild(script) 
} 
関連する問題