【发布时间】:2020-04-13 09:02:52
【问题描述】:
我正在构建一个 react-leaflet 应用程序,并且我试图将缩放控件与地图本身分开。这里提出了香草传单上下文中的相同问题:Placing controls outside map container with Leaflet?。这就是我试图在 react-leaflet 框架内完成的工作。这是我的项目的概要:
import UIWindow from './UIWindow'
import Map from './MapRL'
class App extends React.Component {
render () {
return (
<div className="App">
<Map />
<UIWindow />
</div>
)
}
}
export default App;
我的地图组件如下所示:
import React from 'react'
import { Map as LeafletMap, TileLayer } from 'react-leaflet'
class Map extends React.Component {
render () {
return(
<LeafletMap
className="sidebar-map"
center={...}
zoom={...}
zoomControl={false}
id="mapId" >
<TileLayer
url="..."
attribution="...
/>
</LeafletMap>
)
}
}
export default Map;
然后我的 UIWindow 是这样的:
class UIWindow extends React.Component {
render () {
return(
<div className="UIWindow">
<Header />
<ControlLayer />
</div>
)
}
}
最后,我的 ControlLayer(我希望 ZoomControl 存在的地方)应该如下所示:
class ControlLayer extends React.Component {
render () {
return (
<div className="ControlLayer">
<LeftSidebar />
<ZoomControl />
{this.props.infoPage && <InfoPage />}
</div>
)
}
}
当然,对于当前的代码,将 ZoomControl 放在 ControlLayer 中会引发错误:TypeError: Cannot read property '_zoom' of undefined,更详细地记录了问题所在,以及所有参考资料传单关于缩放功能的内部代码。
(DomUtil.removeClass(this._zoomInButton, className);等)
我预计会出现错误,因为 ZoomControl 不再是 <Map /> 组件的子组件,而是 <Map /> 兄弟组件的孙子组件。我知道它的上下文提供者和消费者、LeafletProvider 和 LeafletConsumer 上的 react-leaflet 函数。当我尝试从<ControlLayer /> 中调用我的 LeafletConsumer 时,我什么也得不到。例如:
<LeafletConsumer>
{context => console.log(context)}
</LeafletConsumer>
这会记录一个空对象。显然,我的 ControlLayer 中的 LeafletConsumer 没有正确连接到我的 <Map /> 中的 LeaflerProvider。我是否需要使用 LeafletProvider 以某种方式从地图中导出上下文?我对 React Context API 有点陌生,所以这对我来说还不直观。 (应用程序的大部分其余部分将使用 React Redux 来管理状态更改和组件之间的通信。这就是我计划将侧边栏的内容连接到地图本身的方式。我的侧边栏似乎没有任何问题与<Map />完全断开)。
如何正确地将这个 ZoomControl 连接到我的地图组件?
更新:
我尝试在我的 redux 存储中捕获上下文,然后将其提供给我的外部化 ZoomControl。像这样:
<LeafletConsumer>
{ context => {
this.props.captureContext(context)
}}
</LeafletConsumer>
这会将上下文捕获为我的 redux 存储的一部分。然后我将其用作新上下文中的值:
// ControlLayer.js
const MapContext = React.createContext()
<MapContext.Provider value={this.props.mapContext}>
<LeftSidebar />
<MapContext.Consumer>
{context => {
if (context){
console.log(ZoomControl);
}
}}
</MapContext.Consumer>
</MapContext.Provider>
this.props.mapContext 是从我的 redux matchStateToProps 引入的,它正是 captureContext 函数捕获的上下文。
不过,这不起作用。我的反应开发工具显示,当 ZoomControl 位于地图组件中时,MapContent.Consumer 提供的值与反应传单固有的 '' 提供的值完全相同。但我仍然收到相同的错误消息。在这里很沮丧。
【问题讨论】:
标签: javascript reactjs leaflet react-context react-leaflet