簡體   English   中英

HTML腳本在React組件加載后加載

[英]HTML script is loading AFTER react components

我的index.html

<!DOCTYPE html>
<html lang="en">
    <head>

        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta name="google-signin-client_id" content= "my_client_id.apps.googleusercontent.com">

        <meta name="google-signin-scope" content="profile email">
        <script src="https://apis.google.com/js/client:platform.js?onload=start" async defer></script>
        <script>
            function start() {
                console.log('script running')
                gapi.load('auth2', function() {
                    auth2 = gapi.auth2.init({
                        client_id: 'my_client_id.apps.googleusercontent.com',
                        scope: 'profile email'
                    });
                });
            }
        </script>
    <title>React App</title>
  </head>
  <body>
    <div id="root"></div>


  </body>
</html>

start()函數中,我打印到控制台以查看其何時運行。

當我加載頁面時,每隔很長時間start()都會 react組件之后加載。

Login.js

    componentDidMount() {
        console.log(gapi.auth2.getAuthInstance())
    }

在調試器中,您可以看到腳本正在組件之后加載:

在此處輸入圖片說明

如果我刷新頁面幾次,則可以正常工作。 但是有時它起作用,有時卻不起作用。

為什么?

我認為在React中加載腳本的最好方法是使用容器組件。 這是一個非常簡單的組件,它允許您編寫將腳本導入組件的邏輯,而不是index.html。 您還將要通過在檢入componentDidMount之后調用loadScript來確保不多次包含腳本。

改編自: https : //www.fullstackreact.com/articles/how-to-write-a-google-maps-react-component/

這樣的事情。

  componentDidMount() {
    if (!window.google) {
      this.loadMapScript();
    }
    else if (!window.google.maps) {
      this.loadMapScript();
    }
    else {
      this.setState({ apiLoaded: true })
    }
  }

  loadMapScript() {
    // Load the google maps api script when the component is mounted.

    loadScript('https://maps.googleapis.com/maps/api/js?key=YOUR_KEY')
      .then((script) => {
        // Grab the script object in case it is ever needed.
        this.mapScript = script;
        this.setState({ apiLoaded: true });
      })
      .catch((err: Error) => {
        console.error(err.message);
      });
  }

  render() {
    return (
      <div className={this.props.className}>
        {this.state.apiLoaded ? (
          <Map
            zoom={10}
            position={{ lat: 43.0795, lng: -75.7507 }}
          />
        ) : (
          <LoadingCircle />
        )}
      </div>
    );
  }

然后在一個單獨的文件中:

const loadScript = (url) => new Promise((resolve, reject) => {
  let ready = false;
  if (!document) {
    reject(new Error('Document was not defined'));
  }
  const tag = document.getElementsByTagName('script')[0];
  const script = document.createElement('script');

  script.type = 'text/javascript';
  script.src = url;
  script.async = true;
  script.onreadystatechange = () => {
    if (!ready && (!this.readyState || this.readyState === 'complete')) {
      ready = true;
      resolve(script);
    }
  };
  script.onload = script.onreadystatechange;

  script.onerror = (msg) => {
    console.log(msg);
    reject(new Error('Error loading script.'));
  };

  script.onabort = (msg) => {
    console.log(msg);
    reject(new Error('Script loading aboirted.'));
  };

  if (tag.parentNode != null) {
    tag.parentNode.insertBefore(script, tag);
  }
});


export default loadScript;

我知道很多東西,但是當我第一次這樣做的時候,當我發現有一種(相當)簡單的方法將任何腳本包含在任何react組件中時,這真讓我感到寬慰。

編輯:其中一些我只是復制粘貼,但是如果您不使用create-react-app,則可能必須替換某些ES6語法。

我的建議:

將您的google API腳本標記更改為this,在其中刪除asyncdefer

<script src="https://apis.google.com/js/client:platform.js"></script>

擺脫掉啟動函數,該函數現在可以正常運行console.log ,但第二部分代碼將引起相同的問題,因為它也將異步運行。

修改您的反應代碼,以便componentWillMount代替地調用該函數的內容:

componentWillMount() {
  gapi.load('auth2', () => {
    auth2 = gapi.auth2.init({
      client_id: 'urhaxorid.apps.googleusercontent.com',
      scope: 'profile email',
      onLoad: () => {
        this.setState({ mapLoaded: true });
      }
    });
  });
}

componentDidMount() {
  if (this.state.mapLoaded) {
    console.log(gapi.auth2.getAuthInstance());
  }
}

請記住,我不知道Google api的onLoad是什么,並且我不確定100%如何最好地完成setState ,但這可能是一個起步。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM