我在 React 中使用常规 Mapbox GL,但在自定义标记上显示弹出窗口时遇到问题。
我尝试使用
addSource
和 addLayer
以及 map.on("click")
事件来弹出窗口,并且它有效。但是,当我尝试仅使用自定义标记时,创建的弹出窗口将我想要显示的内容传递给它,但将 _container
和 _map
记录为 undefined
,因此它不显示。
下面的代码位于函数组件内。
我使用的弹出功能适用于默认的 Mapbox 图层项目,但不适用于我的自定义标记。
const popUpRef = useRef(new mapboxgl.Popup({ offset: 15 }))
function createPopUp(currentFeature) {
const popupNode = document.createElement("div")
const root = createRoot(popupNode)
root.render(
<Popup price={currentFeature.price} />
)
popUpRef.current
.setLngLat(currentFeature.geometry.coordinates)
.setDOMContent(popupNode)
.addTo(map.current)
}
与弹出窗口配合使用的默认标记:
useEffect(() => {
if (!map.current) return; // wait for map to initialize
map.current.on('load', () => {
map.current.addSource('data', {
'type': 'geojson',
'data': data
});
map.current.addLayer({
id: 'unclustered-point',
type: 'circle',
source: 'data'
});
map.current.on("click", e => {
const features = map.current.queryRenderedFeatures(e.point, {
layers: ["unclustered-point"]
});
if (!features.length) return;
const clickedPoint = features[0];
createPopUp(clickedPoint)
})
})
},[])
我需要与弹出窗口一起使用的自定义标记:
const markerClicked = (feature) => {
createPopUp(feature)
};
const Marker = ({ onClick, children, feature }) => {
const _onClick = () => {
onClick(feature);
};
return (
<button onClick={_onClick} className="marker">
{children}
</button>
);
}
useEffect(() => {
if (!map.current) return; // wait for map to initialize
map.current.on('load', () => {
data.features.forEach((feature) => {
const ref = React.createRef();
ref.current = document.createElement("div");
const priceJSX = <Typography variant='p'>{feature.price}</Typography>
const root = createRoot(ref.current)
root.render(
<Marker onClick={markerClicked} feature={feature} children={priceJSX} />
);
new mapboxgl.Marker(ref.current)
.setLngLat(feature.geometry.coordinates)
.addTo(map.current);
});
})
}, [])
当我控制台记录自定义标记的
popUpRef
时,我看到 _container
和 _map
是 undefined
,但是使用默认标记定义了它们,即使我使用相同的函数。
我什至尝试将从
map.on("click")
函数获得的确切功能传递给自定义标记的 onClick
,但它仍然不起作用。
有人能明白为什么我无法在自定义标记上显示弹出窗口吗?
有人遇到类似问题并找到解决方案吗?
我遇到了同样的问题,我设法做了一个肮脏的解决方法所以我正在寻找一个更干净的解决方案。
我还有
_container
和 _map
作为 undefined
。
我推迟了addTo(map)
的行动。它可以工作,但是当弹出窗口关闭时,它仍然是地图上的弹出锚点,我不知道为什么,所以必须手动删除 DOM 元素...
useEffect(() => {
popup
.setLngLat(coordinates)
.setDOMContent(popupRef.current);
// _map & _container : undefined
// so delay the addTo map
setTimeout(() => popup.addTo(map), 10);
return () => {
...
// Clean the remaining anchor
document.querySelectorAll('.mapboxgl-popup').forEach(el => el.remove());
};
}, [])