【发布时间】:2020-05-01 17:26:03
【问题描述】:
这是我的另一个问题的更通用版本:Remove Zoom control from map in react-leaflet。 React-leaflet 带有一些控制地图的组件 - 即<ZoomControl />、<LayersControl /> 等。但是为了使这些组件与地图实例正确通信,它们必须编写为 @ 的子987654327@组件,像这样:
<Map center={...} zoom={...}>
<ZoomControl />
<LayersControl />
<MyCustomComponent />
</Map>
我正在尝试创建一种情况,即不是地图直接子级的地图组件可以与地图正确通信。例如:
<App>
<Map />
<Sibling>
<Niece>
<ZoomControl />
<OtherControls />
</Niece>
</Sibling>
</App>
显然这里的问题是当这些控件不再是<Map /> 的子控件或后代时,它们不会通过提供程序接收地图实例。正如您在my other question 中看到的那样,我尝试创建一个新的 Context 对象并使用它为移位控件提供地图。那没有用,我不知道为什么。到目前为止,我的解决方案是使用 vanilla javascript 在其预期父级的componentDidMount 中重新定位这些控件,如下所示:
// Niece.js
componentDidMount(){
const newZoomHome = document.querySelector('#Niece')
const leafletZoomControl= document.querySelector('.leaflet-control-zoom')
newZoomHome.appendChild(leafletZoomControl)
}
我真的很讨厌这个,因为现在我的通用组件结构并不能反映应用程序结构。我的 Zoom 需要作为我的地图的一部分编写,但最终会出现在我的 Neice 组件中。
Kboul 在我的另一个问题中的解决方案是简单地从头开始重建缩放组件并为其提供地图上下文。这适用于简单的缩放组件,但对于更复杂的组件,我无法重建整个框架。比如我做了一个esri-leaflet's geosearch的quick react-leaflet组件版:
import { withLeaflet, MapControl } from "react-leaflet";
import * as ELG from "esri-leaflet-geocoder";
class GeoSearch extends MapControl {
createLeafletElement(props) {
const searchOptions = {
...props,
providers: props.providers ? props.providers.map( provider => ELG[provider]()) : null
};
const GeoSearch = new ELG.Geosearch(searchOptions);
// Author can specify a callback function for the results event
if (props.onResult){
GeoSearch.addEventListener('results', props.onResult)
}
return GeoSearch;
}
componentDidMount() {
const { map } = this.props.leaflet;
this.leafletElement.addTo(map);
}
}
export default withLeaflet(GeoSearch);
当在<Map /> 组件中声明时,它相对简单并且效果很好。但我想将它移动到应用程序中的单独位置,并且我不想重新编码整个 esri Geosearch。如何在 <Map /> 组件之外使用功能正常的 react-leaflet 控制组件,同时将其正确链接到地图实例?
如果您愿意,这里有一个快速的codsandbox template 开始搞乱。感谢阅读。
【问题讨论】:
标签: javascript reactjs custom-component react-context react-leaflet