Mapbox Popup only opens once and never again
Asked Answered
K

4

8

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.

Kleinstein answered 4/3, 2022 at 8:17 Comment(2)
I have tried console.logging some more and noticed that once I close the initial popup, onClose runs right after clicking on the pin ...Kleinstein
It was a bug in react-map-gl. It's fixed now.Desmond
P
17

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

Ppm answered 7/3, 2022 at 22:43 Comment(1)
That fixed my problem, if you are having the same problem just set closeOnClick={false} and onClose { () => {setShowPopup(false) }}Haulage
U
4

I had the same issue and fixed this more 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 is null or equal to previous value.

Lets try to use this trick for the popup :) - use the lat and lng values to generate the key

<Popup key={popup.lat + popup.lng} latitude={popup.lat} longitude={popup.lng}>
  {popup.children}
</Popup>
Unpaged answered 21/7, 2023 at 14:19 Comment(0)
I
0

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:

onMarkerClick = (marker) => {
    marker.togglePopup();
}
Imperceptible answered 4/3, 2022 at 14:2 Comment(0)
M
0

I had that issue before , try

  onClick={e => {       
        e.originalEvent.stopPropagation();
        setShowPopup(pin._id)}}

then set ,

onClose={() => setShowPopup(false)}>

also set

Metameric answered 12/5, 2022 at 19:1 Comment(1)
You appear to have a trailing sentence at the end of your answer. What exactly needs to be set?Endless

© 2022 - 2024 — McMap. All rights reserved.