React+TypeScript中react-map-gl的MapBox标记无法渲染问题求助
问题
使用React+TypeScript开发MapBox地图组件,基于react-map-gl库。地图能正常渲染并自动定位到标记数据的中心位置,但标记完全不显示,IDE和控制台均无报错信息。
原组件代码:
import React, { useState } from "react"; import ReactMapGL, { Marker } from "react-map-gl"; import getCenter from "geolib/es/getCenter"; function Map({ searchResults }: { searchResults: Array<any> }) { const [selectedLocation, setSelectedLocation] = useState(); const coords = searchResults.map((result) => ({ latitude: result.lat, longitude: result.long, })); const center = getCenter(coords); const [viewport, setViewport] = useState({ latitude: center ? center.latitude : 0, longitude: center ? center.longitude : 0, zoom: 8, }); console.log(selectedLocation); return ( <ReactMapGL mapStyle="mapbox://styles/levanter/cld8rfy27001w01oc8m0sl8pk" mapboxAccessToken={process.env.mapbox_key} style={{ width: "100%", height: "100%", }} initialViewState={{ ...viewport }} onMove={(evt) => setViewport(evt.viewState)} > {searchResults.map((result) => { return ( <div key={result.long}> <Marker longitude={result.long} latitude={result.lat} // anchor="bottom" // offset={[-20, -10]} > <p className="cursor-pointer text-2xl animate-bounce" onClick={() => setSelectedLocation(result)} > 📌 </p> </Marker> </div> ); })} </ReactMapGL> ); } export default Map;
测试数据:
[ { "img": "https://links.papareact.com/xqj", "location": "Private room in center of London", "title": "Stay at this spacious Edwardian House", "description": "1 guest · 1 bedroom · 1 bed · 1.5 shared bthrooms · Wifi · Kitchen · Free parking · Washing Machine", "star": 4.73, "price": "£30 / night", "total": "£117 total", "long": -0.0022275, "lat": 51.5421655 }, { "img": "https://links.papareact.com/hz2", "location": "Private room in center of London", "title": "Independant luxury studio apartment", "description": "2 guest · 3 bedroom · 1 bed · 1.5 shared bthrooms · Wifi · Kitchen", "star": 4.3, "price": "£40 / night", "total": "£157 total", "long": -0.095091, "lat": 51.48695 }, { "img": "https://links.papareact.com/uz7", "location": "Private room in center of London", "title": "London Studio Apartments", "description": "4 guest · 4 bedroom · 4 bed · 2 bathrooms · Free parking · Washing Machine", "star": 3.8, "price": "£35 / night", "total": "£207 total", "long": -0.135638, "lat": 51.521916 }, { "img": "https://links.papareact.com/6as", "location": "Private room in center of London", "title": "30 mins to Oxford Street, Excel London", "description": "1 guest · 1 bedroom · 1 bed · 1.5 shared bthrooms · Wifi · Kitchen · Free parking · Washing Machine", "star": 4.1, "price": "£55 / night", "total": "£320 total", "long": -0.069961, "lat": 51.472618 }, { "img": "https://links.papareact.com/xhc", "location": "Private room in center of London", "title": "Spacious Peaceful Modern Bedroom", "description": "3 guest · 1 bedroom · 1 bed · 1.5 shared bthrooms · Wifi · Free parking · Dry Cleaning", "star": 5.0, "price": "£60 / night", "total": "£450 total", "long": -0.08472, "lat": 51.510794 }, { "img": "https://links.papareact.com/pro", "location": "Private room in center of London", "title": "The Blue Room In London", "description": "2 guest · 1 bedroom · 1 bed · 1.5 shared bthrooms · Wifi · Washing Machine", "star": 4.23, "price": "£65 / night", "total": "£480 total", "long": -0.094116, "lat": 51.51401 }, { "img": "https://links.papareact.com/8w2", "location": "Private room in center of London", "title": "5 Star Luxury Apartment", "description": "3 guest · 1 bedroom · 1 bed · 1.5 shared bthrooms · Wifi · Kitchen · Free parking · Washing Machine", "star": 3.85, "price": "£90 / night", "total": "£650 total", "long": -0.109889, "lat": 51.521245 } ]
解决方案
标记不显示的核心原因是Marker组件被外层div包裹,破坏了react-map-gl的定位逻辑,其次是缺少必要的锚点属性导致位置偏移。
修改步骤
- 移除Marker外层的div,直接将Marker作为
ReactMapGL的子元素(Marker依赖地图上下文进行坐标转换,外层div会脱离该上下文) - 启用
anchor="bottom"属性,确保标记的底部对准坐标点,避免偏移到不可见区域 - 优化key值,使用
lat+long组合确保唯一(原key用result.long存在重复风险) - 给标记文本增加颜色类,避免和地图背景色冲突
修改后的代码
import React, { useState } from "react"; import ReactMapGL, { Marker } from "react-map-gl"; import getCenter from "geolib/es/getCenter"; function Map({ searchResults }: { searchResults: Array<any> }) { const [selectedLocation, setSelectedLocation] = useState(); const coords = searchResults.map((result) => ({ latitude: result.lat, longitude: result.long, })); const center = getCenter(coords); const [viewport, setViewport] = useState({ latitude: center ? center.latitude : 0, longitude: center ? center.longitude : 0, zoom: 8, }); return ( <ReactMapGL mapStyle="mapbox://styles/levanter/cld8rfy27001w01oc8m0sl8pk" mapboxAccessToken={process.env.mapbox_key} style={{ width: "100%", height: "100%", }} initialViewState={{ ...viewport }} onMove={(evt) => setViewport(evt.viewState)} > {searchResults.map((result) => ( <Marker key={`${result.lat}-${result.long}`} longitude={result.long} latitude={result.lat} anchor="bottom" > <p className="cursor-pointer text-2xl animate-bounce text-red-600" onClick={() => setSelectedLocation(result)} > 📌 </p> </Marker> ))} </ReactMapGL> ); } export default Map;
内容的提问来源于stack exchange,提问作者Tsabary
相关产品推荐
相关产品推荐

