Возникли проблемы при получении пользовательской кнопки масштабирования в React-Leaflet

Я пытаюсь создать свою собственную кнопку Zoom с react-leaflet

У меня есть следующий код:

import React from 'react';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import { Map, TileLayer } from 'react-leaflet';
import Control from 'react-leaflet-control';
import FloatingActionButton from 'material-ui/FloatingActionButton';
import ZoomIn from 'material-ui/svg-icons/action/zoom-in';
import ZoomOut from 'material-ui/svg-icons/action/zoom-out';


class LeafletMap extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            animate: true,
            center: [
                -34.989610443115,
                -71.232476234436
            ],
            zoom: 13,
            zoomControl: false
        };
    }

    render() {
        return (
            <div>
                <Map
                    animate={this.state.animate} 
                    center={this.state.center} 
                    zoom={this.state.zoom} 
                    zoomControl={this.state.zoomControl}
                    >
                    <TileLayer
                        url={'http://{s}.tile.osm.org/{z}/{x}/{y}.png'}
                        attribution={'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a>'}
                    />
                    <Control position="topleft">
                        <MuiThemeProvider>
                            <div>
                                <div>&nbsp;</div>
                                <FloatingActionButton mini={true}>
                                    <ZoomIn onClick={ () => alert('Zoom In') } />
                                </FloatingActionButton>
                                <div>&nbsp;</div>
                                <FloatingActionButton mini={true}>
                                    <ZoomOut onClick={ () => alert('Zoom Out') }/>
                                </FloatingActionButton>
                            </div>
                        </MuiThemeProvider>
                    </Control>
                </Map>
            </div>
        );
    }
}
export default LeafletMap;

Все это показывает хороший путь, но теперь я хочу добавить функцию, в которой я могу увеличивать или уменьшать масштаб. У меня нет идеи, как вызывать методы листовки, используя библиотеку реагировать.
Я пробовал много способов реализовать это, но безуспешно.

У вас есть идеи, как это реализовать?

С уважением!

1 ответ

Решение

Есть несколько способов обработки функций / действий на карте.

  1. Пройти через реквизит

Многие варианты доступны через MapРеквизит (границы, центр, зум). Этот способ позволяет вам держать масштаб в одном вашем штате / магазине, а не в листовке.

const React = window.React;
const {
  Map, 
  TileLayer, 
  Marker, 
  Popup
} = window.ReactLeaflet;

class ZoomInState extends React.Component {
  constructor() {
    super();
    this.state = {
      lat: 51.505,
      lng: -0.09,
      zoom: 13,
    };
    this.zoomIn = () => this.setState({zoom: this.state.zoom+1})
    this.zoomOut = () => this.setState({zoom: this.state.zoom-1})
  }

  render() {
    const position = [this.state.lat, this.state.lng];
    return ( < Map center = {
        position
      }
      zoom = {
        this.state.zoom
      }

      >
      < TileLayer attribution = '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
      url = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png' / >
      < Marker position = {
        position
      } >
        < Popup >
          < span >
            <button onClick={this.zoomOut}>
              Zoom out
            </button >
            < button onClick = {this.zoomIn} >
              Zoom in
            < /button>
          < /span>
        </Popup >
      < /Marker>
      </Map >
    );
  }
}
export default ZoomInState
  1. Получить карту через ссылки

Этот способ не будет удерживать уровень масштабирования в вашем компоненте. Часто это хорошая практика, потому что она содержит единый источник правды. Вы всегда можете получить масштаб с map.getZoom()

const React = window.React;
const { Map, TileLayer, Marker, Popup } = window.ReactLeaflet;

class MapByRef extends React.Component {
  constructor() {
    super();
    this.state = {
      lat: 51.505,
      lng: -0.09,
      zoom: 13,
    };
  }

  bindMap(el) {
    this.map = el.leafletElement;
  }

  zoomIn() {
    this.map.zoomIn();
  }

  zoomOut() {
    this.map.zoomOut();
  }

  render() {
    const position = [this.state.lat, this.state.lng];
    return (
      <Map center={position} zoom={this.state.zoom} ref={::this.bindMap}>
        <TileLayer
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
        />
        <Marker position={position}>
          <Popup>
            <span>
              <button onClick={::this.zoomIn} >Zoom In</button>
              <button onClick={::this.zoomIn} >Zoom Out</button>
            </span>
          </Popup>
        </Marker>
      </Map>
    );
  }
}
export default MapByRef

3. Получить из контекста

Этот способ хорош, если вы хотите создать много дочерних компонентов, которые должны взаимодействовать с картой. Это также держит листовку как единственный источник правды.

const React = window.React;
const { Map, TileLayer, Marker, Popup } = window.ReactLeaflet;

class CustomMarker {

  zoomIn(){
    this.context.map.zoomIn()
  }
  zoomOut(){
    this.context.map.zoomOut()
  }

  render() {
    return (
      <Marker position={position}>
        <Popup>
          <button onCLick={::this.zoomIn}>Zoom In</button>
          <button onCLick={::this.zoomOut}>Zoom In</button>
        </Popup>
      </Marker>
    )
  }
}
export CustomMarker


class MapWithCustomChildren extends React.Component {
  constructor() {
    super();
    this.state = {
      lat: 51.505,
      lng: -0.09,
      zoom: 13,
    };
  }

  render() {
    const position = [this.state.lat, this.state.lng];
    return (
      <Map center={position} zoom={this.state.zoom}>
        <TileLayer
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
        />
        <CustomMarker />
      </Map>
    );
  }
}
export default MapWithCustomChildren
Другие вопросы по тегам