I having an issue trying to resize my map using fitbounds
on load.
So I can use handleClick
is correctly resizing the map but when I the fitToCustomLayer
never works as this.mapRef.current
& this.groupRef.current
are always null.
How can I get the fitbounds
to trigger on load?
import React, {createRef, useRef, Component} from "react";
import {Link} from "react-router-dom";
import {MapContainer, TileLayer, Marker, Popup, FeatureGroup, useMapEvents} from "react-leaflet";
import L from "leaflet";
class Map extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.mapRef = createRef();
this.groupRef = createRef();
this.locations = null;
this.state = {
error: null,
isLoaded: false,
data: null,
};
}
async componentDidMount() {
const el = document.getElementById('root')
const url = el.dataset.baseurl + 'maps/display/' + el.dataset.mapid;
try {
fetch(url)
.then(res => res.json())
.then(
(result) => {
if (result.success) {
this.setState({
isLoaded: true,
data: result.data,
});
}
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
} catch (err) {
console.log('error',err);
}
//let mapInst = this.mapRef.current.leafletElement;
//const group = this.groupRef.current.leafletElement; //get native featureGroup instance
//mapInst.fitBounds(group.getBounds());
//const map = useMap();
}
createMarkers() {
const {data} = this.state;
this.locations = Object.values(data.locations)
return this.locations.map(function (item) {
return (
<Marker key={item.id} position={[item.map.lat, item.map.lng]}>
<Popup>
<h4>{item.name} 1</h4>
</Popup>
</Marker>
)
})
}
handleClick() {
let map = this.mapRef.current;
let group = this.groupRef.current;
map.fitBounds(group.getBounds());
}
fitToCustomLayer() {
if (this.mapRef.current && this.groupRef.current) { //we will get inside just once when loading
const map = this.mapRef.current
const group = this.groupRef.current
map.fitBounds(group.getBounds().pad(0.5))
}
}
render() {
const {error, isLoaded, data} = this.state;
if (error) {
return (
<div>Error: {error.message}</div>
);
} else if (!isLoaded) {
return (
<div>Loading...</div>
);
} else {
let locations = Object.values(data.locations);
return (
<div>
<button onClick={this.handleClick}>Zoom</button>
<MapContainer ref={this.mapRef} center={[data.lat, data.long]}
zoom={13} scrollWheelZoom={false} onlayeradd={this.fitToCustomLayer()} >
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<FeatureGroup ref={this.groupRef}>
{this.createMarkers()}
</FeatureGroup>
</MapContainer>
<ul>
{locations.map((item, idx) => (
<li key={item.id}>
{item.name}
<Link to={"location/" + item.slug}>Details</Link>
</li>
))}
</ul>
</div>
);
}
}
}
export default Map;