React+react-leaflet+Framework7 点击FAB按钮实现地图定位到当前位置
实现方案
核心原因是react-leaflet的MapContainer生成的map实例仅能在其内部子组件通过官方hook访问,外层组件无法直接获取,只需要把内部的map实例暴露到外层可访问的作用域即可,具体修改步骤如下:
- 在组件顶部引入
useRefhook,以及react-leaflet提供的useMap方法 - 在Map主组件中创建ref用来存储map实例
- 新增一个挂载在MapContainer内部的轻量辅助组件,通过
useMap拿到map实例后赋值给外层ref - 移除LocationMarker里原有的地图点击触发定位的逻辑
- 在Fab按钮的点击回调中,通过ref拿到map实例后调用
locate()方法触发定位
修改后的完整可运行代码如下:
import React, { useState, useRef } from "react"; import { MapContainer, TileLayer, useMapEvents, useMap, Marker, Popup } from "react-leaflet"; import "../css/leaflet.css"; import "../css/app.css"; import {Fab, Icon, PageContent} from "framework7-react"; // 辅助组件:仅用于将map实例暴露给外层ref function MapController({ mapRef }) { const map = useMap(); mapRef.current = map; return null; } export default function Map(){ // 存储map实例的ref const mapRef = useRef(null); const [position, setPosition] = useState(null); function LocationMarker() { const map = useMapEvents({ // 移除原有的click触发定位逻辑 locationfound(e) { setPosition(e.latlng) map.flyTo(e.latlng, map.getZoom()) }, locationerror(e) { alert("Unfortunately, we could not find your location") } }) return position === null ? null : ( <Marker position={position}> <Popup>You are here</Popup> </Marker> ) } function fabGoToCurrentPosition() { // 加判空避免组件初始化未完成时点击报错 if (mapRef.current) { mapRef.current.locate(); } } return ( <> <Fab position="right-bottom" slot="fixed" id="fab-button" onClick={fabGoToCurrentPosition}> <Icon f7="placemark_fill" ios="f7:placemark_fill" aurora="f7:placemark_fill"></Icon> </Fab> <PageContent className='page-content-map'> <MapContainer center={[51.505, -0.09]} zoom={13} scrollWheelZoom={true} id="map"> <TileLayer attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> {/* 挂载辅助组件传入ref */} <MapController mapRef={mapRef} /> <LocationMarker/> </MapContainer> </PageContent> </> ); }
如果不需要在组件其他位置使用定位坐标,position状态也可以继续留在LocationMarker组件内部,不影响功能,只要移除原有的click事件监听即可
内容的提问来源于stack exchange,提问作者Faker HD
相关产品推荐
相关产品推荐

