You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+react-leaflet+Framework7 点击FAB按钮实现地图定位到当前位置

实现方案

核心原因是react-leaflet的MapContainer生成的map实例仅能在其内部子组件通过官方hook访问,外层组件无法直接获取,只需要把内部的map实例暴露到外层可访问的作用域即可,具体修改步骤如下:

  • 在组件顶部引入useRef hook,以及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='&copy; <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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 08:09:19