簡體   English   中英

React 中帶有類的外部腳本

[英]External script with classes in React

我正在嘗試將外部 map 服務嵌入到我的 React 應用程序中。 他們建議將 API 集成到常規 HTML web 頁面中,如下所示:

<script type="text/javascript" src="//map.search.ch/api/map.js"></script>
<script type="text/javascript">new SearchChMap({center:[123456,987654],y:"-1m",poigroups:"default"});</script>

我嘗試在我的typescript React 組件中應用它,如下所示:

declare class SearchChMap {
  constructor(_: {})
}

// ...

<>
  <script type="text/javascript" src="//map.search.ch/api/map.js"></script>
  <script type="text/javascript">{new SearchChMap({ center: [123456, 987654], poigroups: "default" })}</script>
  {/* ... */}
</>

編譯時,我收到以下運行時錯誤: ReferenceError: SearchChMap is not defined

從 React 組件的外部托管腳本中使用舊版 JavaScript 類的正確方法是什么?

更新:

我嘗試了這個答案無濟於事,使用以下代碼:

componentDidMount(): void {
  const script1: HTMLScriptElement = document.createElement("script");
  script1.src = "//map.search.ch/api/map.js";
  script1.async = true;
  document.body.appendChild(script1);

  const script2: HTMLScriptElement = document.createElement("script");
  script2.text = 'new SearchChMap({center:[123456,987654],y:"-1m",poigroups:"default"});';
  script2.async = true;
  document.body.appendChild(script2);
}

這會在幾秒鍾后導致完全相同的錯誤消息,因為腳本是動態添加的。

更新 2:

按照 AWolf 的建議,將AWolf創建移動到onload就可以了:

componentDidMount(): void {
  const scriptTag: HTMLScriptElement = document.createElement("script");
  scriptTag.src = "//map.search.ch/api/map.js";
  document.head.appendChild(scriptTag);

  scriptTag.onload = () => {
    new SearchChMap({ center: this.props.center, container: this.props.containerId });
  };
}

您可以將腳本標簽添加到public/index.html並將其與window.SearchChMap一起使用,或者如果您更喜歡從您的componentDidMount加載它,您可以像下面的代碼片段一樣執行它(與以下沙箱中的代碼相同)。

它使用附加腳本標簽的onload來延遲 object 的創建,直到新腳本被加載。

使用了useRef ,因此您可以在 function 的其他位置使用創建的 object(示例中未使用)。

需要代碼中的useEffect來確保在添加標簽之前 DOM 已經准備好。 與具有componentDidMount生命周期方法的基於類的組件中的行為相同。 useEffect的返回可用於進行清理,例如return () => { /* remove script tag & dispose the window.SearchChMap */} (與componentWillUnmount相同)

import React, { useEffect, useRef } from "react";

export default () => {
  const SearchMap = useRef(); // optional, but useful if the Map object is used after mounting
  useEffect(() => {
    const scriptTag = document.createElement("script");
    scriptTag.src = "//map.search.ch/api/map.js";
    document.body.appendChild(scriptTag);

    scriptTag.onload = () => {
      SearchMap.current = new window.SearchChMap({ center: "Zürich" });
    };
  }, [SearchMap]);

  return (
    <div
      id="mapcontainer"
      style={{ maxWidth: "500px", height: "400px", border: "2px inset #ccc" }}
    />
  );
};

暫無
暫無

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

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