Mapbox 弹出窗口仅打开一次,再也不会打开
我正在创建一个 React Mapbox 应用程序,但我遇到了弹出窗口问题。 当我渲染地图时,所有标记都正确显示在地图上。然后我单击标记,该标记上会打开一个弹出窗口,其中包含正确的数据和所有内容。
但是,一旦我关闭该弹出窗口,我就无法打开新的弹出窗口。甚至不是同一个弹出窗口。我尝试 console.log() 我点击时获得的数据,它是正确的(引脚数据的对象:纬度,经度,id ...)
这是我的代码:
import { useState, useEffect } from "react";
import Map, { Marker, Popup } from "react-map-gl";
import axios from "axios";
import "mapbox-gl/dist/mapbox-gl.css";
import "./App.css";
import { Room } from "@material-ui/icons";
import { format } from "timeago.js";
function App() {
const [pins, setPins] = useState([]);
//Contains selected pin
const [selectedPin, setSelectedPin] = useState(null);
const [showPopup, setShowPopup] = useState(false);
//Get all pins from the database
useEffect(() => {
const getPins = async () => {
try {
const response = await axios.get("/pins");
setPins(response.data);
} catch (error) {
console.log(error);
}
};
getPins();
//console.log(pins);
}, []);
useEffect(() => {
const listener = (e) => {
if (e.key === "Escape") {
setSelectedPin(null);
}
};
window.addEventListener("keydown", listener);
return () => {
window.removeEventListener("keydown", listener);
};
}, []);
const handlePinClick = (pin) => {
console.log("here");
setSelectedPin(pin);
console.log(pin);
};
return (
<div className="App">
<Map
initialViewState={{
longitude: 31.1656,
latitude: 48.3794,
zoom: 5,
}}
style={{ width: "100vw", height: "100vh" }}
mapStyle="mapbox://styles/msude/cl0b56qxj000215qj1qgx7faq"
mapboxAccessToken={process.env.REACT_APP_MAPBOX}
>
{pins.map((pin) => (
<>
<Marker longitude={pin.long} latitude={pin.lat} anchor="bottom">
<Room
style={{ color: "red", cursor: "pointer" }}
onClick={() => {
handlePinClick(pin);
}}
/>
</Marker>
{selectedPin && (
<Popup
key={selectedPin._id}
longitude={selectedPin.long}
latitude={selectedPin.lat}
anchor="bottom"
onClose={() => setSelectedPin(null)}
>
<div className="popup">
<label>Title</label>
<h2>{selectedPin.title}</h2>
<label>Description</label>
<h2>{selectedPin.description}</h2>
<label>Type of forces</label>
<label>Est. number of forces</label>
<h2>{selectedPin.number}</h2>
<label>Added on</label>
<h2>{format(selectedPin.createdAt)}</h2>
</div>
</Popup>
)}
</>
))}
</Map>
</div>
);
}
export default App;
我一定错过了一些东西,但我一直在努力这两天遇到这个问题,似乎找不到解决方案。
I am creating a React Mapbox App, and I have an issue with popups.
When I render the map, all the Markers show correctly on the map. Then I click on the Marker and a Popup on that marker opens, with correct data and everything.
However, once I close that Popup I can't open a new Popup. Not even the same Popup. I tried to console.log() the data I get on click, and it is correct (object of pin data: lat, long, id ...)
Here is my code:
import { useState, useEffect } from "react";
import Map, { Marker, Popup } from "react-map-gl";
import axios from "axios";
import "mapbox-gl/dist/mapbox-gl.css";
import "./App.css";
import { Room } from "@material-ui/icons";
import { format } from "timeago.js";
function App() {
const [pins, setPins] = useState([]);
//Contains selected pin
const [selectedPin, setSelectedPin] = useState(null);
const [showPopup, setShowPopup] = useState(false);
//Get all pins from the database
useEffect(() => {
const getPins = async () => {
try {
const response = await axios.get("/pins");
setPins(response.data);
} catch (error) {
console.log(error);
}
};
getPins();
//console.log(pins);
}, []);
useEffect(() => {
const listener = (e) => {
if (e.key === "Escape") {
setSelectedPin(null);
}
};
window.addEventListener("keydown", listener);
return () => {
window.removeEventListener("keydown", listener);
};
}, []);
const handlePinClick = (pin) => {
console.log("here");
setSelectedPin(pin);
console.log(pin);
};
return (
<div className="App">
<Map
initialViewState={{
longitude: 31.1656,
latitude: 48.3794,
zoom: 5,
}}
style={{ width: "100vw", height: "100vh" }}
mapStyle="mapbox://styles/msude/cl0b56qxj000215qj1qgx7faq"
mapboxAccessToken={process.env.REACT_APP_MAPBOX}
>
{pins.map((pin) => (
<>
<Marker longitude={pin.long} latitude={pin.lat} anchor="bottom">
<Room
style={{ color: "red", cursor: "pointer" }}
onClick={() => {
handlePinClick(pin);
}}
/>
</Marker>
{selectedPin && (
<Popup
key={selectedPin._id}
longitude={selectedPin.long}
latitude={selectedPin.lat}
anchor="bottom"
onClose={() => setSelectedPin(null)}
>
<div className="popup">
<label>Title</label>
<h2>{selectedPin.title}</h2>
<label>Description</label>
<h2>{selectedPin.description}</h2>
<label>Type of forces</label>
<label>Est. number of forces</label>
<h2>{selectedPin.number}</h2>
<label>Added on</label>
<h2>{format(selectedPin.createdAt)}</h2>
</div>
</Popup>
)}
</>
))}
</Map>
</div>
);
}
export default App;
I must be missing something, but I have been struggling with this issue for the past two days and can't seem to find the solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
显然,你必须在 Popup 组件中设置 closeOnClick={false} ,closeOnClick 默认设置为 true,closeOnClick 用于在单击地图中的某个位置时关闭弹出窗口,但是,由于某种原因,使用 closeOnClick 似乎不会破坏弹出窗口但仅“隐藏它”,那么您将无法再次显示它,我没有通过将 closeOnClick 保持为 true 找到任何解决方法
apparently, you have to set closeOnClick={false} in your Popup component, closeOnClick is set to true by default, closeOnClick is used to close the popup when you click somewhere in the map, however, for some reason using closeOnClick seems to not destroy the popup but only 'hide it', then you're not able to show it again, i don't have found any workaround by keeping closeOnClick to true
我遇到了同样的问题,并且
修复了
这个更简单的
。React 使用
key
属性来确定是否应该安装组件。当密钥发生变化时,就会安装新的组件。我的猜测是您提供的_id
为null
或等于之前的值。让我们尝试在弹出窗口中使用这个技巧:) - 使用 lat 和 lng 值来生成密钥
I had the same issue and
fixed
thismore simply
.React uses
key
prop in order to determine if a component should be mounted. When the key changes, a new component gets mounted. My guess is that the_id
you are providing isnull
or equal to previous value.Lets try to use this trick for the popup :) - use the lat and lng values to generate the key
地图框标记具有“getPopup().isOpen()”来控制标记弹出窗口是否打开,以及“togglePopup()”来切换标记弹出功能。也许你可以用它们来解决你的问题。
例如,当您单击标记时,您会触发单击事件:
mapbox markers have "getPopup().isOpen()" to control if the markers popup is open and "togglePopup()" to toggle the markers popup functions. maybe you can use them for your problem.
for example when you click on your marker you fire a click event:
我以前也遇到过这个问题,尝试
然后设置,
也设置
I had that issue before , try
then set ,
also set