Can someone help me sort out the correct method for using hooks to update the view parameter?
Currently, using React and Leaflet, I am creating a simple map:
import React, { useState, useEffect, useRef } from 'react'
import { useSelector } from 'react-redux'
import L from 'leaflet'
function SmallMap() {
const markers = useSelector(state => state.markers.markers) || []
const [latLng, setLatLng] = useState([32.77, -99.8])
// create map
const mapRef = useRef()
useEffect(() => {
mapRef.current = L.map('map', {
center: latLng,
zoom: 7,
layers: [
L.tileLayer('https://{s}.tile.openstreetmap/{z}/{x}/{y}.png', {
attribution: ''
}),
]
})
}, [])
// add layer to mapRef
const layerRef = useRef(null)
useEffect(() => {
layerRef.current = L.layerGroup().addTo(mapRef.current)
}, [])
// update points in layerRef
useEffect(
() => {
markers.forEach(point => {
L.marker([
point.location.coordinates[1],
point.location.coordinates[0]
],
{
title: point._id
})
.bindPopup(point.type)
.addTo(layerRef.current)
})
},
[markers]
)
return <div id="map"></div>
}
export default SmallMap
...
now - I want to update the center of the map when the markers
array is updated, so I calculate the center of the coordinates based on the new array of markers:
...
const setCenter = (markers) => {
const ave = (array) => array.reduce((a, b) => a + b, 0) / array.length
const lats = []
const lngs = []
if (markers) {
markers.map((point) => (
lats.push(point.location.coordinates[1])
))
markers.map((point) => (
lngs.push(point.location.coordinates[0])
))
}
setLatLng([ave(lats), ave(lngs)])
}
then, I try to update the map with another hook and a ref:
const centerRef = useRef(null)
useEffect(() => {
setCenter(markers)
centerRef.current = L.map
.setView(latLng, 7)
.addTo(mapRef.current)
},
[markers]
)
but I am getting an error:
TypeError: leaflet__WEBPACK_IMPORTED_MODULE_2___default.a.map.setView is not a function
But I am pretty sure that it is a function -
.6.0.html#map-setview
React and Leaflet
Can someone help me sort out the correct method for using hooks to update the view parameter?
Currently, using React and Leaflet, I am creating a simple map:
import React, { useState, useEffect, useRef } from 'react'
import { useSelector } from 'react-redux'
import L from 'leaflet'
function SmallMap() {
const markers = useSelector(state => state.markers.markers) || []
const [latLng, setLatLng] = useState([32.77, -99.8])
// create map
const mapRef = useRef()
useEffect(() => {
mapRef.current = L.map('map', {
center: latLng,
zoom: 7,
layers: [
L.tileLayer('https://{s}.tile.openstreetmap/{z}/{x}/{y}.png', {
attribution: ''
}),
]
})
}, [])
// add layer to mapRef
const layerRef = useRef(null)
useEffect(() => {
layerRef.current = L.layerGroup().addTo(mapRef.current)
}, [])
// update points in layerRef
useEffect(
() => {
markers.forEach(point => {
L.marker([
point.location.coordinates[1],
point.location.coordinates[0]
],
{
title: point._id
})
.bindPopup(point.type)
.addTo(layerRef.current)
})
},
[markers]
)
return <div id="map"></div>
}
export default SmallMap
...
now - I want to update the center of the map when the markers
array is updated, so I calculate the center of the coordinates based on the new array of markers:
...
const setCenter = (markers) => {
const ave = (array) => array.reduce((a, b) => a + b, 0) / array.length
const lats = []
const lngs = []
if (markers) {
markers.map((point) => (
lats.push(point.location.coordinates[1])
))
markers.map((point) => (
lngs.push(point.location.coordinates[0])
))
}
setLatLng([ave(lats), ave(lngs)])
}
then, I try to update the map with another hook and a ref:
const centerRef = useRef(null)
useEffect(() => {
setCenter(markers)
centerRef.current = L.map
.setView(latLng, 7)
.addTo(mapRef.current)
},
[markers]
)
but I am getting an error:
TypeError: leaflet__WEBPACK_IMPORTED_MODULE_2___default.a.map.setView is not a function
But I am pretty sure that it is a function -
https://leafletjs./reference-1.6.0.html#map-setview
React and Leaflet
so I worked this out - here is the basic solution for setting view on the mapRef instance:
useEffect(
() => {
mapRef.current.setView(mapCenter, 6)
},
[markers]
)
more specifically, I did not need to create an additional useRef
instance. Also, I changed the format fo the mapRef instance a bit as well.
// create map
useEffect(
() => {
mapRef.current = L.map('map', {
layers: [
L.tileLayer('https://{s}.tile.openstreetmap/{z}/{x}/{y}.png')
]
})
.setView(mapCenter, 7)
},
[]
)