javascript - 用 Mapbox 更新 props 的正确方法
问题描述
使用 Mapbox 删除和添加源/图层的正确方法是什么?我正在使用 React,并且在data
更新源道具时遇到问题并出现错误。据我在 Mapbox 文档中阅读的内容,removeSource
应在再次添加之前将其删除,但它不适用于组件更新。
错误:已存在具有此 ID 的来源
componentDidMount() {
const { data } = this.props;
this.map = new mapboxgl.Map(config);
}
componentWillUnmount() {
const map = this.map;
map.remove();
map.removeControl(Draw, 'top-left');
}
shouldComponentUpdate(props, nextProps) {
const { data } = props;
if (JSON.stringify(data) !== JSON.stringify(nextProps.data)) {
return true;
}
return false;
}
componentDidUpdate(prevProps) {
const { data } = this.props;
if (JSON.stringify(data) !== JSON.stringify(prevProps.data)) {
this.fetchMap();
}
}
fetchMap() {
const map = this.map;
const { data } = this.props;
map.addControl(Draw, 'top-left');
map.on("load", (e) => {
if (data.features !== null) {
if (map.getSource("locations")) {
map.removeSource("locations");
}
map.addSource("locations", {
type: "geojson",
data: data
});
}
})
}
解决方案
问题是您map.addSource
在组件生命周期中多次调用。
如果我理解正确,您要实现什么,那么您应该将地图load
事件处理程序移至该componentDidMount
方法:
componentDidMount() {
const { data } = this.props;
const map = new mapboxgl.Map(config);
map.addControl(Draw, 'top-left');
map.once("load", (e) => {
map.addSource("locations", {
type: "geojson",
data: data
});
this.setState({ mapIsLoaded: true });
});
this.map = map;
}
在地图完成加载后,请注意使用map.once
而不是map.on
设置状态变量。mapIsLoaded
现在您可以在componentDidUpdate
加载地图后处理源更新:
componentDidUpdate(prevProps) {
const { data } = this.props;
const { mapIsLoaded } = this.state;
if (!mapIsLoaded) {
return;
}
if (data !== prevProps.data) {
this.map.getSource("locations").setData(data);
}
}
而已。
顺便说一句,我是Mapbox GL JS 的 React Component Library的作者。该项目旨在尽可能接近 Mapbox GL JS API。
例如,这是您可以使用库重写代码的方式:
<MapGL mapStyle='mapbox://styles/mapbox/light-v9'>
<Source id='locations' type='geojson' data={data} />
<Layer
id='locations'
type='circle'
source='locations'
paint={{
'circle-radius': 6,
'circle-color': '#1978c8'
}}
/>
<Draw />
</MapGL>
推荐阅读
- mqtt - 如何将我的主题路由到 mqtt 代理中的客户端
- ios - 向可滚动的 UITextView 添加渐变背景
- node.js - 如何使用 cqrs 模块在 nestjs 中进行查询?
- lighttable - Lighttable 中的字体显示不正确
- ios - NSDateFormat 是什么 1991-07-26T05:45:50.163
- mongodb - 提高 MongoDB 上聚合查询的性能
- java - JOOQ - 如何创建主键
- c# - 玩家死亡后将多个游戏对象移动/重生到原始位置
- c# - 将数据从 C# 表单发送到节点服务器 socket.io
- obiee - 代理的接收者取决于 OBIEE 中的分析