从react-leaflet中的地图中删除Zoom控件 [英] Remove Zoom control from map in react-leaflet

查看:287
本文介绍了从react-leaflet中的地图中删除Zoom控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个react-leaflet应用程序,并且试图将缩放控件与地图本身分开.在这里,在香草Leaflet上下文中提出了相同的问题:在地图外部放置控件装有Leaflet的容器​​?.这就是我要在react-leaflet框架内完成的工作.这是我的项目的概述:

I am building a react-leaflet application, and I am trying to separate the zoom control from the map itself. The same question in a vanilla Leaflet context was asked here: Placing controls outside map container with Leaflet?. This is what I'm trying to accomplish within the react-leaflet framework. Here is the general outline of my project:

import UIWindow from './UIWindow'
import Map from './MapRL'

class App extends React.Component {
   render () {
      return (
         <div className="App">
            <Map />
            <UIWindow />
         </div>
      )
   }
}

export default App;

我的地图组件如下所示:

My map component looks like this:

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如下所示:

Then my UIWindow looks like this:

class UIWindow extends React.Component {
   render () {
      return(
         <div className="UIWindow">
            <Header />
            <ControlLayer />
         </div>
      )
   }
}

最后,我的ControlLayer(我想让ZoomControl驻留在其中)应该看起来像这样:

And finally, my ControlLayer (where I want my ZoomControl to live) should look something like this:

class ControlLayer extends React.Component {
   render () {
      return (
         <div className="ControlLayer">
            <LeftSidebar />
            <ZoomControl />
            {this.props.infoPage && <InfoPage />}
         </div>
      )
   }
}

当然,使用当前代码,将ZoomControl放入ControlLayer会引发错误: TypeError:无法读取未定义的属性'_zoom',其中包含所有引用的详细信息有关缩放功能的Leaflet内部代码. (DomUtil.removeClass(this._zoomInButton, className);等)

Of course with this current code, putting ZoomControl in the ControlLayer throws an error: TypeError: Cannot read property '_zoom' of undefined, with some more detailed writeup of what's wrong, with all the references the Leaflet's internal code regarding the zoom functionality. (DomUtil.removeClass(this._zoomInButton, className);, etc.)

我预计会出现错误,因为ZoomControl不再是<Map />组件的子代,而是<Map />的同级子代.我知道其上下文提供者和使用者,LeafletProvider和LeafletConsumer上的react-leaflet函数.当我尝试从<ControlLayer />内部调用LeafletConsumer时,我什么也没回来.例如:

I expected an error, because the ZoomControl is no longer a child of the <Map /> component, but rather a grandchild of the <Map />'s sibling. I know react-leaflet functions on its context provider and consumer, LeafletProvider and LeafletConsumer. When I try to call on my LeafletConsumer from within my <ControlLayer />, I get nothing back. For example:

            <LeafletConsumer>
               {context => console.log(context)}
            </LeafletConsumer>

这将记录一个空对象.显然,我的ControlLayer中的LeafletConsumer没有正确地从我的<Map />钩接到LeaflerProvider中.我是否需要使用LeafletProvider从Map导出上下文?我对React Context API有点陌生,所以这对我来说还不直观. (该应用程序的其余大部分将使用React Redux来管理状态更改和组件之间的通信.这就是我计划将侧边栏的内容连接到地图本身的方式.我的侧边栏似乎没有任何问题与<Map />完全断开).

This logs an empty object. Clearly my LeafletConsumer from my ControlLayer is not properly hooked into the LeaflerProvider from my <Map />. Do I need to export the context from the Map somehow using LeafletProvider? I am a little new to React Context API, so this is not yet intuitive for me. (Most of the rest of the app will be using React Redux to manage state changes and communication between components. This is how I plan to hook up the contents of the sidebar to the map itself. My sidebar doesn't seem to have any problem with being totally disconnected from the <Map />).

如何正确地将此ZoomControl挂钩到我的Map组件上?

How can I properly hook this ZoomControl up to my Map component?

更新:

我尝试在我的redux存储中捕获上下文,然后将其提供给我的外部化ZoomControl.像这样:

I tried capturing the context in my redux store, and then serving it to my externalized ZoomControl. Like so:

            <LeafletConsumer>
               { context => {
                  this.props.captureContext(context)
               }}
            </LeafletConsumer>

这会将上下文捕获为我的redux存储的一部分.然后,我将其用作新上下文中的值:

This captures the context as part of my redux store. Then I use this as a value in a new context:

// 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函数捕获的.

Where this.props.mapContext is brought in from my redux matchStateToProps, and its exactly the context captured by the captureContext function.

仍然,这不起作用.我的react开发工具显示,当ZoomControl在Map组件内时,MapContent.Consumer给出的值与react-leaflet固有的''值完全相同.但是我仍然收到相同的错误消息.在这里非常沮丧.

Still, this is not working. My react dev tools show that the MapContent.Consumer is giving the exact same values as react-leaflet's inherent '' gives when the ZoomControl is within the Map component. But I still get the same error message. Very frustrated over here.

推荐答案

这里是没有钩子的相同方法:

Here is the same approach without hooks:

提供程序应如下所示:

class Provider extends Component {
  state = { map: null };

  setMap = map => {
    this.setState({ map });
  };

  render() {
    return (
      <Context.Provider value={{ map: this.state.map, setMap: this.setMap }}>
        {this.props.children}
      </Context.Provider>
    );
  }
}

传单组成为:

class Leaflet extends Component {
  mapRef = createRef(null);

  componentDidMount() {
    const map = this.mapRef.current.leafletElement;
    this.props.setMap(map);
  }

  render() {
    return (
      <Map
        style={{ width: "80vw", height: "60vh" }}
        ref={this.mapRef}
        center={[50.63, 13.047]}
        zoom={13}
        zoomControl={false}
        minZoom={3}
        maxZoom={18}
      >
        <TileLayer
          attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?"
        />
      </Map>
    );
  }
}

现在要访问seto函数到compoenntDidMount,您需要执行以下操作:

and now to access the setMap function to the compoenntDidMount you need to do the following:

export default props => (
  <Context.Consumer>
    {({ setMap }) => <Leaflet {...props} setMap={setMap} />}
  </Context.Consumer>
);

其余的请看这里:演示

这篇关于从react-leaflet中的地图中删除Zoom控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆