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

React中无直接关联的Markers组件点击时如何向App传递经纬度?

React组件跨层级传递经纬度解决方案

你的组件层级为 App -> Map -> CurrentLocationMap -> Markers,需要将Markers的点击经纬度传递到App组件,以下是两种常用实现方式:

方式一:Props逐层传递(适合层级较少的场景)

通过在组件间逐层传递回调函数,实现子组件到父组件的状态回传。

1. 修改App组件,定义状态和回调

import { useState } from 'react';
import { Router, Routes, Route } from 'react-router-dom';
import Map from './Map';
import ShowImgFromSide from './ShowImgFromSide';

function App() {
  const [selectedLatLng, setSelectedLatLng] = useState(null);

  // 接收Markers传递的经纬度
  const handleMarkerClick = (latlng) => {
    setSelectedLatLng(latlng);
    console.log('App收到经纬度:', latlng);
  };

  return (
    <Router>
      {/* 将回调传给Map组件 */}
      <Map onMarkerClick={handleMarkerClick} />
      <Routes>
        <Route exact path="/upload-img" element={<ShowImgFromSide url="http://localhost:5000/uploaded-img" />} />
        <Route exact path="/get-position-img" element={<ShowImgFromSide url={`http://localhost:5000/get-img-position/`} />} />
      </Routes>
    </Router>
  );
}

export default App;

2. 修改Map组件,传递回调到CurrentLocationMap

import CurrentLocationMap from './CurrentLocationMap';

function Map(props) {
  return (
    // 继续将回调传递给CurrentLocationMap
    <CurrentLocationMap onMarkerClick={props.onMarkerClick} />
  );
}

export default Map;

3. 修改CurrentLocationMap组件,传递回调到Markers

import Markers from './Markers';

function CurrentLocationMap(props) {
  // 示例位置数据,替换为你的实际数据
  const markerPositions = [/* {lat: xxx, lng: xxx}, ... */];

  return (
    <div>
      {markerPositions.map((pos, index) => (
        <Markers 
          key={index} 
          position={pos} 
          onMarkerClick={props.onMarkerClick} 
        />
      ))}
    </div>
  );
}

export default CurrentLocationMap;

4. 修改Markers组件,调用回调传递经纬度

import { Marker, Popup, Link } from 'react-leaflet';

export function Markers(props) {
  function onMarkerClick(e) {
    const latlng = e.target._latlng;
    // 调用父组件传递的回调,发送经纬度
    props.onMarkerClick(latlng);
    console.log(latlng);
  }

  return (
    <Marker eventHandlers={{ click: onMarkerClick }} position={props.position} icon={icon}>
      <Popup>
        <p style={{ fontWeight: "bold" }}>My Location</p>
        <Link to="/get-position-img">
          <button style={{ cursor: "pointer" }}>Show Image</button>
        </Link>
      </Popup>
    </Marker>
  );
}

方式二:使用Context API(适合层级较深的场景)

通过React Context实现跨层级状态传递,避免逐层传递props的繁琐。

1. 创建LatLngContext.js

import { createContext, useContext, useState } from 'react';

const LatLngContext = createContext();

// 提供Context的组件
export function LatLngProvider({ children }) {
  const [selectedLatLng, setSelectedLatLng] = useState(null);

  const handleMarkerClick = (latlng) => {
    setSelectedLatLng(latlng);
    console.log('App收到经纬度:', latlng);
  };

  return (
    <LatLngContext.Provider value={{ selectedLatLng, handleMarkerClick }}>
      {children}
    </LatLngContext.Provider>
  );
}

// 自定义Hook,简化Context消费
export function useLatLng() {
  return useContext(LatLngContext);
}

2. 修改App组件,包裹Context Provider

import { Router, Routes, Route } from 'react-router-dom';
import Map from './Map';
import ShowImgFromSide from './ShowImgFromSide';
import { LatLngProvider } from './LatLngContext';

function App() {
  return (
    <LatLngProvider>
      <Router>
        <Map />
        <Routes>
          <Route exact path="/upload-img" element={<ShowImgFromSide url="http://localhost:5000/uploaded-img" />} />
          <Route exact path="/get-position-img" element={<ShowImgFromSide url={`http://localhost:5000/get-img-position/`} />} />
        </Routes>
      </Router>
    </LatLngProvider>
  );
}

export default App;

3. 修改Markers组件,消费Context

import { Marker, Popup, Link } from 'react-leaflet';
import { useLatLng } from './LatLngContext';

export function Markers(props) {
  const { handleMarkerClick } = useLatLng();

  function onMarkerClick(e) {
    const latlng = e.target._latlng;
    // 调用Context中的回调
    handleMarkerClick(latlng);
    console.log(latlng);
  }

  return (
    <Marker eventHandlers={{ click: onMarkerClick }} position={props.position} icon={icon}>
      <Popup>
        <p style={{ fontWeight: "bold" }}>My Location</p>
        <Link to="/get-position-img">
          <button style={{ cursor: "pointer" }}>Show Image</button>
        </Link>
      </Popup>
    </Marker>
  );
}

选择建议

  • 若组件层级不多(3层以内),优先使用Props逐层传递,逻辑简单直观;
  • 若组件层级较深,使用Context API可以避免"props drilling"问题;
  • 若项目复杂度高、状态共享需求多,也可以考虑使用Redux、Zustand等状态管理库。

内容的提问来源于stack exchange,提问作者Arnob10011

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 16:40:40