urbica / react-map-gl

React Component Library for Mapbox GL JS
https://urbica.github.io/react-map-gl/
MIT License
416 stars 50 forks source link

Popup not rendering on click #553

Open davidjentjens opened 1 year ago

davidjentjens commented 1 year ago

I am trying to implement a Popup functionality when a user clicks on the markers on the Map. This is the relevant part of the code:

App.tsx

import 'mapbox-gl/dist/mapbox-gl.css'

import ReactGLMap from '@urbica/react-map-gl'
import { useState } from 'react'

import MarkerControl from './components/MarkerControl'

export const App = () => {
  const [viewport, setViewport] = useState({
    latitude: 0,
    longitude: 0,
    zoom: 0,
  })

  return (
    <div style={{ width: 600, height: 400 }}>
      <ReactGLMap
        {...viewport}
        mapStyle="mapbox://styles/mapbox/satellite-v9"
        accessToken={TOKEN}
        style={{ width: '100%', height: '100%' }}
        onViewportChange={setViewport}
      >
        <MarkerControl />
      </ReactGLMap>
    </div>
  )
}

MarkerControl.tsx

import { Marker, Popup } from '@urbica/react-map-gl'
import { MapMouseEvent } from 'mapbox-gl'
import { useState } from 'react'

import Pin from '../../../../icons/Pin'
import { COLORS } from '../../../../utils/COLORS'
import { useGeoMap } from '../../provider/GeoMapProvider'
import { MarkerData } from './utils/Marker.props'

const MarkerControl = () => {
  const { markers } = useGeoMap()

  const [showPopup, setShowPopup] = useState(false)
  const [selectedMarker, setSelectedMarker] = useState<MarkerData>()

  const handleShowMarker = (e: MapMouseEvent, markerData: MarkerData) => {
    e.originalEvent.stopPropagation()
    setShowPopup(true)
    setSelectedMarker(markerData)
  }

  return (
    <>
      {showPopup && selectedMarker && (
        <Popup
          closeButton={true}
          key={selectedMarker!.lngLat.lng + selectedMarker!.lngLat.lat}
          longitude={selectedMarker!.lngLat.lng}
          latitude={selectedMarker!.lngLat.lat}
          anchor="bottom"
          onClose={() => setShowPopup(false)}
          closeOnClick={false}
        >
          {selectedMarker.title}
          <br />
          {selectedMarker.description}
        </Popup>
      )}
      {markers.map((marker) => (
        <Marker
          key={marker.id}
          latitude={marker.lngLat.lat}
          longitude={marker.lngLat.lng}
          onClick={(e) => handleShowMarker(e, marker)}
        >
          {marker.icon || <Pin color={marker.color || COLORS.white} />}
        </Marker>
      ))}
    </>
  )
}

export default MarkerControl

However, when the user clicks on a marker, nothing happens. I know I can make a Popup appear if I just write it inside the returning JSX, without any conditional rendering. I also tested the boolean values showPopup and selectedMarker, to make sure it wasn't a pure logic problem.

To Reproduce Steps to reproduce the behavior:

  1. Install @urbica/react-map-gl and mapbox-gl
  2. Replicate my code, changing the useGeoMap hook to some simple state management
  3. Run the App
  4. See error

Expected behavior I expected a Popup to appear when the user clicks on a Marker, based on the code above.

Screenshots Popup not popping up :(

Desktop (please complete the following information):

Additional context The useGeoMap hook is nothing but externalized state management for the markers, since I am adding them outside of the MarkerControl component. Any additional requested code will be provided as soon as requested.

Thanks in advance for any help provided! :)