I'm trying to build my own Zoom button with react-leaflet
I have the following code:
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/{z}/{x}/{y}.png'}
attribution={'© <a href=";>OpenStreetMap</a>'}
/>
<Control position="topleft">
<MuiThemeProvider>
<div>
<div> </div>
<FloatingActionButton mini={true}>
<ZoomIn onClick={ () => alert('Zoom In') } />
</FloatingActionButton>
<div> </div>
<FloatingActionButton mini={true}>
<ZoomOut onClick={ () => alert('Zoom Out') }/>
</FloatingActionButton>
</div>
</MuiThemeProvider>
</Control>
</Map>
</div>
);
}
}
export default LeafletMap;
All this is displaying good way, but now I want to to put a funcion where I can able to do zoom in or out. I don't have an idea how to call leaflet's methods using react-leaflet library.
I've tried many ways to implement it but without success.
Do you have any idea how to implement it?
I'm trying to build my own Zoom button with react-leaflet
I have the following code:
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/{z}/{x}/{y}.png'}
attribution={'© <a href="http://osm/copyright">OpenStreetMap</a>'}
/>
<Control position="topleft">
<MuiThemeProvider>
<div>
<div> </div>
<FloatingActionButton mini={true}>
<ZoomIn onClick={ () => alert('Zoom In') } />
</FloatingActionButton>
<div> </div>
<FloatingActionButton mini={true}>
<ZoomOut onClick={ () => alert('Zoom Out') }/>
</FloatingActionButton>
</div>
</MuiThemeProvider>
</Control>
</Map>
</div>
);
}
}
export default LeafletMap;
All this is displaying good way, but now I want to to put a funcion where I can able to do zoom in or out. I don't have an idea how to call leaflet's methods using react-leaflet library.
I've tried many ways to implement it but without success.
Do you have any idea how to implement it?
Share Improve this question edited Jan 13, 2021 at 13:08 Enlico 28.6k8 gold badges67 silver badges152 bronze badges asked Jul 24, 2016 at 0:15 Javier MuñozJavier Muñoz 7901 gold badge13 silver badges31 bronze badges1 Answer
Reset to default 5There are a few ways to handle map functions/actions.
- Pass via props
Many options are available via the Map
's props(bounds, center, zoom). This way allows you to hold the zoom in your one state/store, instead of in leaflet.
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 = '© <a href="http://osm/copyright">OpenStreetMap</a> contributors'
url = 'http://{s}.tile.osm/{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
- Get map via refs
This way will not hold the zoom level in your ponent. Often this is a good practice, because it keeps a single source of truth. You can always get the zoom with 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='© <a href="http://osm/copyright">OpenStreetMap</a> contributors'
url='http://{s}.tile.osm/{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. Get from Context
This way is nice if you want to make many child ponents that need to interact with the map. It also keeps leaflet as the single source of truth.
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='© <a href="http://osm/copyright">OpenStreetMap</a> contributors'
url='http://{s}.tile.osm/{z}/{x}/{y}.png'
/>
<CustomMarker />
</Map>
);
}
}
export default MapWithCustomChildren