javascript - React 中带有类的外部脚本
问题描述
我正在尝试将外部地图服务嵌入到我的 React 应用程序中。他们建议将 API 集成到常规 HTML 网页中,如下所示:
<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:
将对象创建移动到onload
建议AWolf
的技巧:
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
附加的脚本标签来延迟对象的创建,直到新脚本被加载。
使用useRef
了,因此您可以在函数的其他位置使用创建的对象(示例中未使用)。
代码中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" }}
/>
);
};
推荐阅读
- javascript - 使用新用户输入重复通过 Firebase 显示的数据
- python - 如何获取和修改嵌套字典的值?
- javascript - 在所有网站上阻止一个 html 类名
- java - 对于未执行的语句
- c++ - 将 QByteArray 从大端转换为小端
- android - Firebase 身份验证在卸载后保存。我怎样才能删除它?
- python - 重加权距离返回与使用 iris 数据集的 knn 中的常规距离相同的结果
- arrays - 如何从numpy中的矩阵中选择具有来自另一个向量的值的列
- java - 如何在java中运行时在json字符串中添加容器节点
- python - 在其他包中导入模块会导致错误