Всплывающие окна маркера Mapbox не открываются / закрываются индивидуально - PullRequest
0 голосов
/ 02 апреля 2020

Когда пользователь добавляет добавленный маркер на мою карту, он открывает всплывающие окна для всех маркеров на карте enter image description here

Всплывающие окна открываются для отдельного выбранного маркера для маркеров, загруженных в базу данных, но для 'setShowUserPopup' они открываются для каждого отдельного маркера, добавленного пользователем, как показано на фотографии (формы являются всплывающим содержимым)

Спасибо за любую помощь заранее!

import React, { useState, useEffect } from "react";
import ReactMapGL, { Marker, Popup } from "react-map-gl";

import { listLogEntries } from "./API";
import LogEntryForm from "./LogEntryForm";
import { Grid, Card, Icon, Fab } from "@material-ui/core";

const BasicMap = () => {
  // Markers loaded from database
  const [logEntries, setLogEntries] = useState([]);
  const [showPopup, setShowPopup] = useState({});

  // Markers from user input
  const [userMarkers, setUserMarkers] = useState([]);
  const [showUserPopup, setShowUserPopup] = useState({});

  // viewport is all the infomation about the default map state
  const [viewport, setViewport] = useState({
    width: "100vw",
    height: "100vh",
    latitude: 52.950001,
    longitude: -1.15,
    zoom: 6,
    minZoom: 3
    // maxZoom: 3
  });

  // Get entries from API

  const getEntries = async () => {
    const logEntries = await listLogEntries();
    setLogEntries(logEntries);
  };

  useEffect(() => {
    getEntries();
  }, []);

  const showAddMarkerPopup = event => {
    const [longitude, latitude] = event.lngLat;

    setUserMarkers([
      ...userMarkers,
      {
        id: userMarkers.length + 1,
        lat: latitude,
        long: longitude,
        draggable: true
      }
    ]);
  };

  useEffect(() => {
    console.log("userMarkers", userMarkers);
  }, [userMarkers]);

  return (
    <ReactMapGL
      {...viewport}
      mapStyle="mapbox://styles/veleter/ck7xdy1yo1bkj1ipmsbhe9c96"
      mapboxApiAccessToken={process.env.REACT_APP_MAPBOX_TOKEN}
      onViewportChange={setViewport}
      onClick={showAddMarkerPopup}
    >
      {/* DATABASE LOADED MARKERS */}
      {logEntries.map(entry => (
        <React.Fragment key={entry._id}>
          <Marker latitude={entry.latitude} longitude={entry.longitude}>
            <div
              onClick={() =>
                setShowPopup({
                  ...showPopup,
                  [entry._id]: true
                })
              }
            >
              <svg
                className="marker yellow"
                style={{
                  height: `${6 * viewport.zoom}px`,
                  width: `${6 * viewport.zoom}px`
                }}
                version="1.1"
                id="Layer_1"
                x="0px"
                y="0px"
                viewBox="0 0 512 512"
              >
                <g>
                  <g>
                    <path
                      d="M256,0C153.755,0,70.573,83.182,70.573,185.426c0,126.888,165.939,313.167,173.004,321.035
                        c6.636,7.391,18.222,7.378,24.846,0c7.065-7.868,173.004-194.147,173.004-321.035C441.425,83.182,358.244,0,256,0z M256,278.719
                        c-51.442,0-93.292-41.851-93.292-93.293S204.559,92.134,256,92.134s93.291,41.851,93.291,93.293S307.441,278.719,256,278.719z"
                    />
                  </g>
                </g>
              </svg>
            </div>
          </Marker>
          {showPopup[entry._id] ? (
            <Popup
              latitude={entry.latitude}
              longitude={entry.longitude}
              closeButton={true}
              closeOnClick={false}
              dynamicPosition={true}
              onClose={() =>
                setShowPopup({
                  ...showPopup,
                  [entry._id]: false
                })
              }
              anchor="top"
            >
              <div className="popup">
                {/* <h3>{entry.title}</h3>
                <p>{entry.comments}</p>
                <p>
                  <b>Longitude: </b>
                  {entry.longitude}
                </p>
                <p>
                  <b>Latitude: </b>
                  {entry.latitude}
                </p>
                <small>
                  Ticket Placed:{" "}
                  {new Date(entry.visitDate).toLocaleDateString()}
                </small>
                {entry.image && <img src={entry.image} alt={entry.title} />} */}

                <Card elevation={3} className="p-4">
                  <div className="flex items-center">
                    <Fab
                      size="medium"
                      className="bg-light-error circle-44 box-shadow-none overflow-hidden"
                    >
                      <Icon className="text-error">star_outline</Icon>
                    </Fab>
                    <h5 className="font-medium text-error m-0 ml-3">
                      {entry.title}
                    </h5>
                  </div>
                  <div className="pt-4 flex items-center">
                    <h2 className="m-0 text-muted flex-grow"></h2>
                    <div className="ml-3 small-circle bg-error text-white"></div>
                    <span className="text-13">({entry.longitude})</span>
                    <span className="text-13">({entry.latitude})</span>
                  </div>
                </Card>
              </div>
            </Popup>
          ) : null}
        </React.Fragment>
      ))}

      {/* USER ADDED MARKER */}

      {userMarkers.map(userMarker => (
        <React.Fragment key={userMarker._id}>
          <Marker
            latitude={userMarker.lat}
            longitude={userMarker.long}
            draggable
            // onDragEnd={setUserMarkers}
          >
            <div
              onClick={() =>
                setShowUserPopup({
                  ...showUserPopup,
                  [userMarker._id]: true
                })
              }
            >
              <div>
                <svg
                  className="marker red"
                  style={{
                    height: `${6 * viewport.zoom}px`,
                    width: `${6 * viewport.zoom}px`
                  }}
                  version="1.1"
                  id="Layer_1"
                  x="0px"
                  y="0px"
                  viewBox="0 0 512 512"
                >
                  <g>
                    <g>
                      <path
                        d="M256,0C153.755,0,70.573,83.182,70.573,185.426c0,126.888,165.939,313.167,173.004,321.035
                        c6.636,7.391,18.222,7.378,24.846,0c7.065-7.868,173.004-194.147,173.004-321.035C441.425,83.182,358.244,0,256,0z M256,278.719
                        c-51.442,0-93.292-41.851-93.292-93.293S204.559,92.134,256,92.134s93.291,41.851,93.291,93.293S307.441,278.719,256,278.719z"
                      />
                    </g>
                  </g>
                </svg>
              </div>
            </div>
          </Marker>

          {showUserPopup[userMarker._id] ? (
            <Popup
              latitude={userMarker.lat}
              longitude={userMarker.long}
              closeButton={true}
              closeOnClick={false}
              dynamicPosition={true}
              onClose={() =>
                setShowUserPopup({
                  ...showUserPopup,
                  [userMarker._id]: false
                })
              }
              anchor="top"
            >
              <div className="popup">
                <LogEntryForm />
              </div>
            </Popup>
          ) : null}
        </React.Fragment>
      ))}
    </ReactMapGL>
  );
};
export default BasicMap;

1 Ответ

1 голос
/ 02 апреля 2020

Ошибка возникает из-за непередачи точного идентификатора на рынок. Когда вы нажимаете на маркер и устанавливаете его на true, вы делаете это для всех маркеров на карте.

Что вам нужно сделать, это передать идентификатор элементу, который нужно открыть, который является модальным, а затем нацелиться на идентификатор с помощью события onClick.

 onClick={e => {
      setShowPopup(e.currentTarget.id);
}}

Затем Чтобы отобразить нужный элемент, вы должны сравнить значение от event до идентификатора:

{userMarkersID === showUserPopup.id && (
      <div>Whatever you wanna show</div>
)}

, где userMarkersID - это идентификатор каждого маркера, который у вас есть на карте. Надеюсь, что это поможет

...