简体   繁体   中英

React, Leaflet - Hooks, setView, and useRef

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.org/{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.com/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.org/{z}/{x}/{y}.png')
                ]
            })
            .setView(mapCenter, 7)
        },
        []
    )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM