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
相关产品推荐
相关产品推荐

