Reputation: 101
I'm using react-map-gl
and states so that when a marker is clicked on the popupOpen
is set to true and the popup shows up.
This works with maps with only one marker but when I use a map fuction to send coords of multiple markers, clicking on any of them opens all popups because the binded state cotrols them all.
How do I set it up so that only the popup related to a specific marker shows up?
// state
const [popupOpen, setPopupOpen] = useState(false);
// marker & popup
{landmarkData.map((data, index) => (
<div key={data._id}>
<Marker
key={index}
longitude={data.longitude}
latitude={data.latitude}
onClick={() => setPopupOpen(true)}
>
<RoomIcon fontSize="small" style={{fill: "red"}} />
</Marker>
{popupOpen && (
<Popup
key={index}
latitude={data.latitude}
longitude={data.longitude}
onClose={() => setPopupOpen(false)}
closeButton={true}
offsetLeft={10}
>
<span style={{fontSize: "1vw", fontFamily: "Poppins"}}>
{data.name}
</span>
</Popup>
)}
</div>
))}
Upvotes: 1
Views: 3254
Reputation: 1
You need to track each popup state individually and then prevent the propagation of the onClick so it does not close.
// state
const [popupOpen, setPopupOpen] = useState({});
// marker & popup
{landmarkData.map((data, index) => (
<div key={data._id}>
<Marker
key={index}
longitude={data.longitude}
latitude={data.latitude}
onClick={(e) => {
// If we let the click event propagate to the map, it will immediately close the popup
// with `closeOnClick: true`
e.originalEvent.stopPropagation();
setPopupOpen({ [data._id]: true });
}}
>
<RoomIcon fontSize="small" style={{fill: "red"}} />
</Marker>
{popupOpen[data._id] && (
<Popup
key={index}
latitude={data.latitude}
longitude={data.longitude}
onClose={() => setPopupOpen(false)}
closeButton={true}
offsetLeft={10}
>
<span style={{fontSize: "1vw", fontFamily: "Poppins"}}>
{data.name}
</span>
</Popup>
)}
</div>
))}
It is similar to @Manish answer (credit to him) but need to prevent the propagation and use setPopupOpen({ [data._id]: true })
if you want to only have one popup at a time.
Upvotes: 0
Reputation: 5213
You should individually track the popup open state; like this:
// state
const [popupOpen, setPopupOpen] = useState({});
// render
{landmarkData.map((data, index) => (
<div key={data._id}>
<Marker
key={index}
longitude={data.longitude}
latitude={data.latitude}
onClick={() => setPopupOpen({...popupOpen, popupOpen[data._id]: true })}
>
<RoomIcon fontSize="small" style={{fill: "red"}} />
</Marker>
{popupOpen[data._id] && (
<Popup
key={index}
latitude={data.latitude}
longitude={data.longitude}
onClose={() => setPopupOpen(false)}
closeButton={true}
offsetLeft={10}
>
<span style={{fontSize: "1vw", fontFamily: "Poppins"}}>
{data.name}
</span>
</Popup>
)}
</div>
))}
Upvotes: 2